-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathVideoDecoder.hpp
More file actions
298 lines (254 loc) · 10.8 KB
/
Copy pathVideoDecoder.hpp
File metadata and controls
298 lines (254 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// SPDX-License-Identifier: BSD-3-Clause-Clear
#ifndef QC_NODE_VIDEO_DECODER_HPP
#define QC_NODE_VIDEO_DECODER_HPP
#include <mutex>
#include <queue>
#include <sys/uio.h>
#include <unordered_map>
#include <vidc_ioctl.h>
#include <vidc_types.h>
#ifndef _VIDC_LRH_LINUX_
#include <ioctlClient.h>
#else
#include <cstring>
#include <vidc_client.h>
#endif
#include "VidcDrvClient.hpp"
#include "QC/Common/Types.hpp"
#include "QC/Infras/Log/Logger.hpp"
#include "QC/Infras/Memory/VideoFrameDescriptor.hpp"
#include "QC/Node/NodeBase.hpp"
#include "VidcNodeBase.hpp"
namespace QC::Node
{
/** @brief The QCNode VideoDecoder Version */
#define QCNODE_VIDEODECODER_VERSION_MAJOR 2U
#define QCNODE_VIDEODECODER_VERSION_MINOR 0U
#define QCNODE_VIDEODECODER_VERSION_PATCH 0U
#define QCNODE_VIDEODECODER_VERSION \
( ( QCNODE_VIDEODECODER_VERSION_MAJOR << 16U ) | ( QCNODE_VIDEODECODER_VERSION_MINOR << 8U ) | \
QCNODE_VIDEODECODER_VERSION_PATCH )
/** @brief This data type list the different VideoDecoder Callback Event Type */
typedef VideoCodec_EventType_e VideoDecoder_EventType_e;
/**
* @brief The VideoDecoder Init Config
* Buffer allocate has three modes:
* dynamic mode: app allocate buffers, told component when SubmitInputFrame() & SubmitOutputFrame().
* We call it mode 1).
* none dynamic mode: different with dynamic mode, none dynamic mode will set buffer address to
* driver before decode. For none dynamic mode, app can allocate buffers, we call it mode 2); if app
* don't allocate, qcnode component will allocate, we call it mode 3). mode 2): app allocate
* buffers, transfer buffer list by init() with bufferList ptr and number. In this mode, bufferList
* ptr must not be nullptr, and app must make sure bufferList number <= bufferList.len(). mode 3):
* app not allocate buffers, and bufferList ptr must be nullptr; and app will tell the buffer number
* requested to component with Init(). When app call init(), qcnode will allocate buffers in
* component.
*/
using VideoDecoder_Config_t = VidcNodeBase_Config_t;
class VideoDecoderConfigIfs : public VidcNodeBaseConfigIfs
{
public:
/**
* @brief VideoDecoderConfigIfs Constructor
* @param[in] logger A reference to the logger to be shared and used by VideoDecoderConfigIfs.
* @param[in] vide A reference to the RideHal Video Decoder component to be used by VideoDecoderConfigIfs.
* VideoDecoderConfigIfs.
* @return None
*/
VideoDecoderConfigIfs( Logger &logger )
: VidcNodeBaseConfigIfs( logger )
{}
/**
* @brief VideoDecoderConfigIfs Destructor
* @return None
*/
virtual ~VideoDecoderConfigIfs() {}
/**
* @brief Verify the configuration string and set the configuration structure.
* @param[in] config The configuration string.
* @param[out] errors The error string returned if there is an error.
* @note The config is a JSON string according to the templates below.
* 1. Static configuration used for initialization:
* {
* "static": {
* "name": "The Node unique name, type: string, default: 'unnamed'",
* "id": "The Node unique ID, type: uint32_t, default: 0",
* "width": "The width in pixels of the I/O frame, type: uint32_t, default: 0",
* "height": "The height in pixels of the I/O frame, type: uint32_t, default: 0",
* "frameRate": "The encoder frames per second, type: uint32_t, default: 0",
* "inputDynamicMode": "If true encoder allocates the buffer for input frames,
* otherwise caller should provide the buffers for input,
* type: bool, default: true",
* "outputDynamicMode": "If true encoder allocates the buffer for output frames,
* otherwise caller should provide the buffers for output,
* type: bool, default: true",
* "numInputBufferReq": "The number of input buffers, type: uint32_t, default: 0",
* "numOutputBufferReq": "The number of output buffers, type: uint32_t, default: 0",
* "inFormat": "input compress mode, now support h264 and h265, type: uint32_t,
* default: h265",
* "outFormat": "output format support NV12, NV12_UBWC, P010, type: uint32_t,
* default: nv12"
* }
* }
* @return QC_STATUS_OK on success, other values on failure.
*/
virtual QCStatus_e VerifyAndSet( const std::string config, std::string &errors );
/**
* @brief Get Configuration Options
* @return A reference string to the JSON configuration options.
* @note
* TODO: Provide a more detailed introduction about the JSON configuration options.
*/
const virtual std::string& GetOptions( )
{
return m_options;
}
/**
* @brief Get the Configuration Structure.
* @return A reference to the Configuration Structure.
*/
const virtual QCNodeConfigBase_t& Get( )
{
return m_config;
}
private:
QCStatus_e ParseStaticConfig( DataTree &dt, std::string &errors );
VideoDecoder_Config_t m_config;
std::string m_options = "{}";
};
typedef struct VideoDecoderMonitorConfig : public QCNodeMonitoringBase_t
{
bool bPerfEnabled;
} VideoDecoderMonitorConfig_t;
class VideoDecoderMonitoringIfs : public QCNodeMonitoringIfs
{
public:
VideoDecoderMonitoringIfs( Logger &logger )
: m_logger( logger )
{}
virtual ~VideoDecoderMonitoringIfs() {}
virtual QCStatus_e VerifyAndSet( const std::string config, std::string &errors )
{
return QC_STATUS_UNSUPPORTED;
}
const virtual std::string& GetOptions( )
{
return m_options;
}
const virtual QCNodeMonitoringBase_t& Get( )
{
return m_config;
}
;
virtual inline uint32_t GetMaximalSize() { return UINT32_MAX; }
virtual inline uint32_t GetCurrentSize() { return UINT32_MAX; }
virtual QCStatus_e Place( void *ptr, uint32_t &size ) { return QC_STATUS_UNSUPPORTED; }
private:
Logger &m_logger;
std::string m_options;
VideoDecoderMonitorConfig_t m_config;
};
typedef enum
{
QC_NODE_VIDEO_DECODER_INPUT_BUFF_ID = 0,
QC_NODE_VIDEO_DECODER_OUTPUT_BUFF_ID = 1,
QC_NODE_VIDEO_DECODER_EVENT_BUFF_ID = 2
} VideoDecoderBufferId_e;
/** @brief Top level control for interfacing with vidc based driver */
class VideoDecoder : public VidcNodeBase
{
public:
/**
* @brief VideoDecoder Constructor
* @return None
*/
VideoDecoder()
: m_configIfs( m_logger ), m_monitorIfs( m_logger )
{
m_state = QC_OBJECT_STATE_INITIAL;
}
/**
* @brief VideoDecoder Destructor
* @return None
*/
virtual ~VideoDecoder() {}
/**
* @brief Initialize Node Video Decoder
* @param[in] config The Node Video Decoder configuration
* @return QC_STATUS_OK on success, others on failure
*/
virtual QCStatus_e Initialize( QCNodeInit_t &config );
/**
* @brief Get the Node Video Decoder configuration interface.
* @return A reference to the Node Video Decoder configuration interface.
*/
virtual inline QCNodeConfigIfs &GetConfigurationIfs() { return m_configIfs; }
/**
* @brief Get the Node Video Decoder monitoring interface.
* @return A reference to the Node Video Decoder monitoring interface.
*/
virtual inline QCNodeMonitoringIfs &GetMonitoringIfs() { return m_monitorIfs; }
/**
* @brief Processes the Frame Descriptor.
* @param[in] frameDesc The frame descriptor containing a vector of input/output buffers.
* @note ProcessFrameDescriptor call will return immediately after queuing the job into the
* backend video encoder engine. Once the inference job is completed, the callback will be
* invoked, making this an asynchronous API.
* @note There are three channels (buffers IDs):
* o) QC_NODE_VIDEO_DECODER_INPUT_BUFF_ID for input
* o) QC_NODE_VIDEO_DECODER_OUTPUT_BUFF_ID for output
* o) QC_NODE_VIDEO_DECODER_INPUT_BUFF_ID for status and error events
* The callback of this function use GetBuffer() passing the required buffer ID
* to specify the required channel, so to get the input and output buffers by the callback
* the following pattern can be used:
* auto &bufIn = GetBuffer( QC_NODE_VIDEO_DECODER_INPUT_BUFF_ID )
* auto &bufOut = GetBuffer( QC_NODE_VIDEO_DECODER_OUTPUT_BUFF_ID );
* @note This API is not thread-safe. Avoid calling the ProcessFrameDescriptor API
* on the same instance from multiple threads simultaneously.
* @return QC_STATUS_OK on success, or an error code on failure.
*/
virtual QCStatus_e ProcessFrameDescriptor( QCFrameDescriptorNodeIfs &frameDesc );
/**
* @brief Get the current state of the Node VideoDecoder
* @return The current state of the Node VideoDecoder
*/
virtual QCObjectState_e GetState() { return m_state; }
virtual QCStatus_e Start();
virtual QCStatus_e Stop();
protected:
/**
* @brief submit a video frame to VIDC driver for encoding
* @param pInput pointer to hold the video frame information
* @return QC_STATUS_OK on success, others on failure
*/
QCStatus_e SubmitInputFrame( VideoFrameDescriptor_t &inFrameDesc );
/**
* @brief submit a video frame back to VIDC driver
* @param pOutput pointer to hold the video frame information
* @return QC_STATUS_OK on success, others on failure
*/
QCStatus_e SubmitOutputFrame( VideoFrameDescriptor_t &outFrameDesc );
QCStatus_e ValidateConfig( );
QCStatus_e HandleOutputReconfig();
QCStatus_e FinishOutputReconfig();
QCStatus_e InitDrvProperty();
QCStatus_e CheckBuffer( const VideoFrameDescriptor_t &frameDesc,
VideoCodec_BufType_e bufferType );
void InFrameCallback( VideoFrameDescriptor_t &inFrameDesc );
void OutFrameCallback( VideoFrameDescriptor_t &outFrameDesc );
void EventCallback( VideoDecoder_EventType_e eventId, const void *pEvent );
private:
VideoDecoderConfigIfs m_configIfs;
VideoDecoderMonitoringIfs m_monitorIfs;
QCNodeEventCallBack_t m_callback;
const VideoDecoder_Config_t *m_pConfig = nullptr;
bool m_OutputStarted = false;
bool m_OutputReconfigInprogress = false;
std::mutex m_reconfigMutex; // Mutex for reconfig state
static void InFrameCallback( VideoFrameDescriptor_t &inFrameDesc, void *pPrivData );
static void OutFrameCallback( VideoFrameDescriptor_t &outFrameDesc, void *pPrivData );
static void EventCallback( VideoCodec_EventType_e eventId, const void *pEvent, void *pPrivData );
};
} // namespace QC::Node
#endif // QC_NODE_VIDEO_DECODER_HPP