Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/va_intel/va_intel_interop.cpp
16337 views
1
/* origin: libva-1.3.1/test/decode/mpeg2vldemo.cpp */
2
3
/*
4
* Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
16
* of the Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
*/
26
27
#include <iostream>
28
#include <stdexcept>
29
#include <string>
30
31
#include <stdio.h>
32
#include <string.h>
33
#include <stdlib.h>
34
#include <getopt.h>
35
#include <unistd.h>
36
#include <sys/types.h>
37
#include <sys/stat.h>
38
#include <fcntl.h>
39
#include <assert.h>
40
#include <va/va.h>
41
42
#include "display.cpp.inc"
43
44
#include "opencv2/core.hpp"
45
#include "opencv2/imgproc.hpp"
46
#include "opencv2/highgui.hpp"
47
#include "opencv2/core/va_intel.hpp"
48
49
#define CHECK_VASTATUS(_status,_func) \
50
if (_status != VA_STATUS_SUCCESS) \
51
{ \
52
char str[256]; \
53
snprintf(str, sizeof(str)-1, "%s:%s (%d) failed(status=0x%08x),exit\n", __func__, _func, __LINE__, _status); \
54
throw std::runtime_error(str); \
55
}
56
57
class CmdlineParser
58
{
59
public:
60
enum { fnInput=0, fnOutput1, fnOutput2, _fnNumFiles }; // file name indices
61
CmdlineParser(int argc, char** argv):
62
m_argc(argc), m_argv(argv)
63
{}
64
void usage()
65
{
66
fprintf(stderr,
67
"Usage: va_intel_interop [-f] infile outfile1 outfile2\n\n"
68
"Interop ON/OFF version\n\n"
69
"where: -f option indicates interop is off (fallback mode); interop is on by default\n"
70
" infile is to be existing, contains input image data (bmp, jpg, png, tiff, etc)\n"
71
" outfile1 is to be created, contains original surface data (NV12)\n"
72
" outfile2 is to be created, contains processed surface data (NV12)\n");
73
}
74
// true => go, false => usage/exit; extra args/unknown options are ignored for simplicity
75
bool run()
76
{
77
int n = 0;
78
for (int i = 0; i < _fnNumFiles; ++i)
79
m_files[i] = 0;
80
m_interop = true;
81
for (int i = 1; i < m_argc; ++i)
82
{
83
const char *arg = m_argv[i];
84
if (arg[0] == '-') // option
85
{
86
if (!strcmp(arg, "-f"))
87
m_interop = false;
88
}
89
else // parameter
90
{
91
if (n < _fnNumFiles)
92
m_files[n++] = arg;
93
}
94
}
95
return bool(n >= _fnNumFiles);
96
}
97
bool isInterop() const
98
{
99
return m_interop;
100
}
101
const char* getFile(int n) const
102
{
103
return ((n >= 0) && (n < _fnNumFiles)) ? m_files[n] : 0;
104
}
105
private:
106
int m_argc;
107
char** m_argv;
108
const char* m_files[_fnNumFiles];
109
bool m_interop;
110
};
111
112
class Timer
113
{
114
public:
115
enum UNITS
116
{
117
USEC = 0,
118
MSEC,
119
SEC
120
};
121
122
Timer() : m_t0(0), m_diff(0)
123
{
124
m_tick_frequency = (float)cv::getTickFrequency();
125
126
m_unit_mul[USEC] = 1000000;
127
m_unit_mul[MSEC] = 1000;
128
m_unit_mul[SEC] = 1;
129
}
130
131
void clear()
132
{
133
m_t0 = m_diff = 0;
134
}
135
136
void start()
137
{
138
m_t0 = cv::getTickCount();
139
}
140
141
void stop()
142
{
143
m_diff = cv::getTickCount() - m_t0;
144
}
145
146
float time(UNITS u = MSEC)
147
{
148
float sec = m_diff / m_tick_frequency;
149
150
return sec * m_unit_mul[u];
151
}
152
153
public:
154
float m_tick_frequency;
155
int64 m_t0;
156
int64 m_diff;
157
int m_unit_mul[3];
158
};
159
160
static void checkIfAvailableYUV420()
161
{
162
VAEntrypoint entrypoints[5];
163
int num_entrypoints,vld_entrypoint;
164
VAConfigAttrib attrib;
165
VAStatus status;
166
167
status = vaQueryConfigEntrypoints(va::display, VAProfileMPEG2Main, entrypoints, &num_entrypoints);
168
CHECK_VASTATUS(status, "vaQueryConfigEntrypoints");
169
170
for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; ++vld_entrypoint)
171
{
172
if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
173
break;
174
}
175
if (vld_entrypoint == num_entrypoints)
176
throw std::runtime_error("Failed to find VLD entry point");
177
178
attrib.type = VAConfigAttribRTFormat;
179
vaGetConfigAttributes(va::display, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1);
180
if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)
181
throw std::runtime_error("Desired YUV420 RT format not found");
182
}
183
184
static cv::UMat readImage(const char* fileName)
185
{
186
cv::Mat m = cv::imread(fileName);
187
if (m.empty())
188
throw std::runtime_error("Failed to load image: " + std::string(fileName));
189
return m.getUMat(cv::ACCESS_RW);
190
}
191
192
static void writeImage(const cv::UMat& u, const char* fileName, bool doInterop)
193
{
194
std::string fn = std::string(fileName) + std::string(doInterop ? ".on" : ".off") + std::string(".jpg");
195
cv::imwrite(fn, u);
196
}
197
198
static float run(const char* infile, const char* outfile1, const char* outfile2, bool doInterop)
199
{
200
VASurfaceID surface;
201
VAStatus status;
202
Timer t;
203
204
// initialize CL context for CL/VA interop
205
cv::va_intel::ocl::initializeContextFromVA(va::display, doInterop);
206
207
// load input image
208
cv::UMat u1 = readImage(infile);
209
cv::Size size2 = u1.size();
210
status = vaCreateSurfaces(va::display, VA_RT_FORMAT_YUV420, size2.width, size2.height, &surface, 1, NULL, 0);
211
CHECK_VASTATUS(status, "vaCreateSurfaces");
212
213
// transfer image into VA surface, make sure all CL initialization is done (kernels etc)
214
cv::va_intel::convertToVASurface(va::display, u1, surface, size2);
215
cv::va_intel::convertFromVASurface(va::display, surface, size2, u1);
216
cv::UMat u2;
217
cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3));
218
219
// measure performance on some image processing
220
writeImage(u1, outfile1, doInterop);
221
t.start();
222
cv::va_intel::convertFromVASurface(va::display, surface, size2, u1);
223
cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3));
224
cv::va_intel::convertToVASurface(va::display, u2, surface, size2);
225
t.stop();
226
writeImage(u2, outfile2, doInterop);
227
228
vaDestroySurfaces(va::display, &surface,1);
229
230
return t.time(Timer::MSEC);
231
}
232
233
int main(int argc, char** argv)
234
{
235
try
236
{
237
CmdlineParser cmd(argc, argv);
238
if (!cmd.run())
239
{
240
cmd.usage();
241
return 0;
242
}
243
244
if (!va::openDisplay())
245
throw std::runtime_error("Failed to open VA display for CL-VA interoperability");
246
std::cout << "VA display opened successfully" << std::endl;
247
248
checkIfAvailableYUV420();
249
250
const char* infile = cmd.getFile(CmdlineParser::fnInput);
251
const char* outfile1 = cmd.getFile(CmdlineParser::fnOutput1);
252
const char* outfile2 = cmd.getFile(CmdlineParser::fnOutput2);
253
bool doInterop = cmd.isInterop();
254
255
float time = run(infile, outfile1, outfile2, doInterop);
256
257
std::cout << "Interop " << (doInterop ? "ON " : "OFF") << ": processing time, msec: " << time << std::endl;
258
}
259
catch (std::exception& ex)
260
{
261
std::cerr << "ERROR: " << ex.what() << std::endl;
262
}
263
264
va::closeDisplay();
265
return 0;
266
}
267
268