Cogs.Core
IVideoDecoder.h
1#pragma once
2
3#include "Resources/Resources.h"
4#include "Rendering/Common.h"
5#include "Rendering/TextureData.h"
6
7#include "Foundation/Platform/Threads.h"
8#include "Foundation/Reflection/Name.h"
9
10#include <map>
11#include <stdint.h>
12
13namespace Cogs {
14 class IGraphicsDevice;
15
16 namespace Core {
17 class Context;
18 struct RenderTexture;
19 struct Texture;
20
21 enum class TransferFunction : uint32_t {
22 Linear,
23 BT601,
24 sRGB,
25 Gamma
26 };
27
28 enum class ColourSpace : uint32_t {
29 BT601,
30 BT601Full,
31 BT709,
32 BT709Full,
33 };
34
36 {
37 class IVideoDecoder* decoder;
38 void* userData;
39 const struct VideoDecoderPayload& payload;
40 const unsigned char* spspps;
41 size_t spspps_size;
42 bool is_idr;
43 bool is_meta;
44 };
45 using VideoDecoderCallback = void(const VideoDecoderCallbackData&);
46
48 {
49 void *data;
50 int64_t timestamp;
51 };
52
53 using VideoPresentCallback = void(const VideoPresentCallbackData&);
54
55 enum struct Codec
56 {
57 None = -1,
58 H264,
59 HEVC
60 };
61
62 enum struct ChromaFormat : unsigned
63 {
64 Monochrome,
65 Chroma420,
66 Chroma422,
67 Chroma444
68 };
69
70 enum struct VideoDecoderPresentMode
71 {
72 Smooth = 1, // Keep a steady framerate
73 Realtime, // Reduce latency while keeping a steady framerate
74 Latest, // Always show the latest frame
75 };
76
78 {
79 const void *data = nullptr;
80 size_t size = 0;
81 int64_t timestamp = 0; // See VideoDecoderDescription::clock_rate for units
82 bool end_of_stream = false;
83 bool discontinuity = false;
84 bool end_of_picture = false;
85 bool use_timestamp = false;
86 };
87
89 {
90 uint64_t clock_rate = 10000000; // Timestamp units in Hz (0=default=10000000Hz)
91 uint32_t error_threshold = 100; // Error threshold (0-100) for presenting
92 // (100=always present even if fully corrupt)
93 uint32_t max_display_delay = 2; // Max display queue delay (improves pipelining of decode with display)
94 // 0=no delay (recommended values: 2..4)
95
96 Codec codec = Codec::H264;
97 std::string vps;
98 std::string sps;
99 std::string pps;
100
101 VideoDecoderPresentMode present_mode = VideoDecoderPresentMode::Smooth;
102 uint32_t speedup_queue_count = 3; // Speedup queue start count for Realtime playback (Increase when using B-frames)
103 float speedup_factor = 1.0f; // Speedup factor is additional playback speed for Realtime playback
104
105 bool generateMipMaps = true; // Generate mipmaps for each decoded frame.
106 bool skip_discontinuities = false;
107 bool recordToDisk = false;
108 std::string recordPath;
109 VideoDecoderCallback* decodeCallback = nullptr;
110 void* decodeCallbackData = nullptr;
111 VideoPresentCallback* presentCallback = nullptr;
112 void* presentCallbackData = nullptr;
113 };
114
116 {
117 int64_t timestamp = -1; // See VideoDecoderDescription::clock_rate for units
118 };
119
121 {
122 Codec codec = Codec::H264;
123 ChromaFormat chroma_format = ChromaFormat::Chroma420;
124 uint32_t bit_depth = 8;
125 };
126
127 class COGSCORE_DLL_API IVideoDecoder {
128 public:
129 struct Rect {
130 int left = -1;
131 int top = -1;
132 int right = -1;
133 int bottom = -1;
134 };
135
136 IVideoDecoder(Context& ctx) : context(ctx) {}
137 virtual ~IVideoDecoder() = default;
138
139 Codec getCodec() const { return codec; }
140 VideoDecoderPresentMode getPresentMode() const { return presentMode; }
141 double getDiscontinuityDuration() const { return discontinuityDuration; }
142 uint32_t getSpeedupQueueCount() const { return speedupQueueCount; }
143 float getSpeedupFactor() const { return speedupFactor; }
144 uint32_t getSurfaceCount() const { return surfaceCount; }
145 uint32_t getChromaFormatIdc() const { return chromaFormatIdc; }
146 uint32_t getChromaBitDepthMinus8() const { return chromaBitDepthMinus8; }
147 uint32_t getLumaBitDepthMinus8() const { return lumaBitDepthMinus8; }
148 uint32_t getCodedWidth() const { return codedWidth; }
149 uint32_t getCodedHeight() const { return codedHeight; }
150 const Rect& getDisplayArea() const { return displayArea; }
151 uint32_t getOutputWidth() const { return outputWidth; }
152 uint32_t getOutputHeight() const { return outputHeight; }
153 ColourSpace getColourSpace() const { return colourSpace; }
154 TransferFunction getTransferFunction() const { return transferFunction; }
155 float getGamma() const { return gamma; }
156 int64_t getClockRate() const { return clockRate; }
157 int64_t getPreviousClock() const { return previousClock; }
158 int64_t getClockResidual() const { return clockResidual; }
159 int64_t getPreviousClockResidual() const { return previousClockResidual; }
160 bool getCheckUnderflow() const { return checkUnderflow; }
161 int64_t getPresentationTime() const { return presentationTime; }
162 int64_t getPreviousPresentationTime() const { return previousPresentationTime; }
163 int64_t getPlayTime() const { return playTime; }
164 int64_t getPreviousPlayTime() const { return previousPlayTime; }
165 uint32_t getBufferUnderflowCounter() const { return bufferUnderflowCounter; }
166 uint32_t getBufferUnderflowMajorStutterCounter() const { return bufferUnderflowMajorStutterCounter; }
167 uint32_t getBufferOverflowCounter() const { return bufferOverflowCounter; }
168 uint32_t getDecoderRestartCounter() const { return decoderRestartCounter; }
169 uint32_t getDiscontinuitiesSkippedCounter() const { return discontinuitiesSkippedCounter; }
170 const TextureDescription& getTextureDescription() const { return textureDesc; }
171 Cogs::TextureHandle getTexture() const { return texture; }
172 RenderTexture* getRenderTexture() const { return renderTexture; }
173
174 bool& refSkipDiscontinuities() { return skipDiscontinuities; }
175 uint32_t& refSpeedupQueueCount() { return speedupQueueCount; }
176 float& refSpeedupFactor() { return speedupFactor; }
177
178 bool shouldSkipDiscontinuities() const { return skipDiscontinuities; }
179
180 void setPresentMode(VideoDecoderPresentMode mode) { presentMode = mode; }
181
182 protected:
183 Context& context;
184 Codec codec = Codec::None;
185 VideoDecoderPresentMode presentMode = VideoDecoderPresentMode::Latest;
186 bool skipDiscontinuities = true;
187 bool generateMipMaps = false;
188 double discontinuityDuration = 0.5;
189 uint32_t surfaceCount = 0;
190 std::vector<uint8_t> parameterSets;
191
192 // Speedup parameters used in Realtime present mode...
193 uint32_t speedupQueueCount = 3;
194 float speedupFactor = 1.0f;
195
196 VideoDecoderCallback* decodeCallback = nullptr;
197 void* decodeCallbackData = nullptr;
198 VideoPresentCallback* presentCallback = nullptr;
199 void* presentCallbackData = nullptr;
200
201 // Video parameters, as decoded from the video parameter sets...
202 uint32_t chromaFormatIdc = static_cast<uint32_t>(-1);
203 uint32_t chromaBitDepthMinus8 = static_cast<uint32_t>(-1);
204 uint32_t lumaBitDepthMinus8 = static_cast<uint32_t>(-1);
205 uint32_t codedWidth = static_cast<uint32_t>(-1);
206 uint32_t codedHeight = static_cast<uint32_t>(-1);
207 Rect displayArea;
208 uint32_t outputWidth = 0;
209 uint32_t outputHeight = 0;
210 ColourSpace colourSpace = ColourSpace::BT709Full;
211 TransferFunction transferFunction = TransferFunction::sRGB;
212 float gamma = 1.0f / 2.2f;
213
214 int64_t clockRate = 0;
215 int64_t previousClock = 0;
216 int64_t clockResidual = 0;
217 int64_t previousClockResidual = 0;
218 bool checkUnderflow = false;
219
220 int64_t presentationTime = 0;
221 int64_t previousPresentationTime = 0;
222
223 int64_t playTime = 0;
224 int64_t previousPlayTime = 0;
225
226 // Debug counters
227 uint32_t bufferUnderflowCounter = 0;
228 uint32_t bufferUnderflowMajorStutterCounter = 0;
229 uint32_t bufferOverflowCounter = 0;
230 uint32_t decoderRestartCounter = 0;
231 uint32_t discontinuitiesSkippedCounter = 0;
232
233 // Output texture
234 TextureDescription textureDesc;
236 RenderTexture* renderTexture = nullptr;
238
239 virtual void cleanup();
240 virtual int64_t getPresentationTime(size_t queuePosition) = 0;
241
242 void parseVideoDescription(const VideoDecoderDescription& desc);
243 void createTexture();
244 int selectDisplayFrame(size_t queueLength);
245 };
246
248 {
249 virtual ~IVideoDecoderContext() = default;
250 virtual void update() = 0;
251
252 virtual bool capsSupported(VideoDecoderCaps &caps) = 0;
253 virtual void loadVideoTexture(Cogs::Core::TextureHandle textureHandle, const VideoDecoderDescription &desc) = 0;
254 virtual void reloadVideoTexture(Cogs::Core::TextureHandle textureHandle, const VideoDecoderDescription &desc) = 0;
255 virtual TextureDescription getVideoDescription(Cogs::Core::TextureHandle textureHandle) = 0;
256 virtual VideoDecoderStatus getVideoStatus(Cogs::Core::TextureHandle textureHandle) = 0;
257 virtual void streamVideoData(Cogs::Core::TextureHandle textureHandle, const VideoDecoderPayload &packet) = 0;
258 virtual void endVideoStream(Cogs::Core::TextureHandle textureHandle) = 0;
259
260 protected:
261 // Pending data is incoming video stream data that can't be processed because the decoder isn't ready.
262 // IVideoDecoderContext implementations are free to discard incoming data that can't be processed, or
263 // package it in a PendingData object and queue it for decoding at at later time.
264
265 struct PendingData {
266 std::vector<uint8_t> data;
267 VideoDecoderPayload payload;
268
269 PendingData(const VideoDecoderPayload& p) : data(static_cast<const uint8_t*>(p.data), static_cast<const uint8_t*>(p.data) + p.size), payload(p) {
270 payload.data = data.data();
271 }
272 };
273
274 using pendingDataMap = std::map<Texture*, std::vector<PendingData>>;
275
276 pendingDataMap pendingData;
277 Mutex pendingDataMutex;
278 };
279 }
280}
281
282template<> inline Cogs::StringView getName<Cogs::Core::Codec>() { return "Codec"; }
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
std::vector< uint8_t > parameterSets
Cached VPS, SPS, and PPS data.
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
@ sRGB
Value is a color and is subject to gamma correction.
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78