Path: blob/master/samples/va_intel/va_intel_interop.cpp
16337 views
/* origin: libva-1.3.1/test/decode/mpeg2vldemo.cpp */12/*3* Copyright (c) 2007-2008 Intel Corporation. All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*/2526#include <iostream>27#include <stdexcept>28#include <string>2930#include <stdio.h>31#include <string.h>32#include <stdlib.h>33#include <getopt.h>34#include <unistd.h>35#include <sys/types.h>36#include <sys/stat.h>37#include <fcntl.h>38#include <assert.h>39#include <va/va.h>4041#include "display.cpp.inc"4243#include "opencv2/core.hpp"44#include "opencv2/imgproc.hpp"45#include "opencv2/highgui.hpp"46#include "opencv2/core/va_intel.hpp"4748#define CHECK_VASTATUS(_status,_func) \49if (_status != VA_STATUS_SUCCESS) \50{ \51char str[256]; \52snprintf(str, sizeof(str)-1, "%s:%s (%d) failed(status=0x%08x),exit\n", __func__, _func, __LINE__, _status); \53throw std::runtime_error(str); \54}5556class CmdlineParser57{58public:59enum { fnInput=0, fnOutput1, fnOutput2, _fnNumFiles }; // file name indices60CmdlineParser(int argc, char** argv):61m_argc(argc), m_argv(argv)62{}63void usage()64{65fprintf(stderr,66"Usage: va_intel_interop [-f] infile outfile1 outfile2\n\n"67"Interop ON/OFF version\n\n"68"where: -f option indicates interop is off (fallback mode); interop is on by default\n"69" infile is to be existing, contains input image data (bmp, jpg, png, tiff, etc)\n"70" outfile1 is to be created, contains original surface data (NV12)\n"71" outfile2 is to be created, contains processed surface data (NV12)\n");72}73// true => go, false => usage/exit; extra args/unknown options are ignored for simplicity74bool run()75{76int n = 0;77for (int i = 0; i < _fnNumFiles; ++i)78m_files[i] = 0;79m_interop = true;80for (int i = 1; i < m_argc; ++i)81{82const char *arg = m_argv[i];83if (arg[0] == '-') // option84{85if (!strcmp(arg, "-f"))86m_interop = false;87}88else // parameter89{90if (n < _fnNumFiles)91m_files[n++] = arg;92}93}94return bool(n >= _fnNumFiles);95}96bool isInterop() const97{98return m_interop;99}100const char* getFile(int n) const101{102return ((n >= 0) && (n < _fnNumFiles)) ? m_files[n] : 0;103}104private:105int m_argc;106char** m_argv;107const char* m_files[_fnNumFiles];108bool m_interop;109};110111class Timer112{113public:114enum UNITS115{116USEC = 0,117MSEC,118SEC119};120121Timer() : m_t0(0), m_diff(0)122{123m_tick_frequency = (float)cv::getTickFrequency();124125m_unit_mul[USEC] = 1000000;126m_unit_mul[MSEC] = 1000;127m_unit_mul[SEC] = 1;128}129130void clear()131{132m_t0 = m_diff = 0;133}134135void start()136{137m_t0 = cv::getTickCount();138}139140void stop()141{142m_diff = cv::getTickCount() - m_t0;143}144145float time(UNITS u = MSEC)146{147float sec = m_diff / m_tick_frequency;148149return sec * m_unit_mul[u];150}151152public:153float m_tick_frequency;154int64 m_t0;155int64 m_diff;156int m_unit_mul[3];157};158159static void checkIfAvailableYUV420()160{161VAEntrypoint entrypoints[5];162int num_entrypoints,vld_entrypoint;163VAConfigAttrib attrib;164VAStatus status;165166status = vaQueryConfigEntrypoints(va::display, VAProfileMPEG2Main, entrypoints, &num_entrypoints);167CHECK_VASTATUS(status, "vaQueryConfigEntrypoints");168169for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; ++vld_entrypoint)170{171if (entrypoints[vld_entrypoint] == VAEntrypointVLD)172break;173}174if (vld_entrypoint == num_entrypoints)175throw std::runtime_error("Failed to find VLD entry point");176177attrib.type = VAConfigAttribRTFormat;178vaGetConfigAttributes(va::display, VAProfileMPEG2Main, VAEntrypointVLD, &attrib, 1);179if ((attrib.value & VA_RT_FORMAT_YUV420) == 0)180throw std::runtime_error("Desired YUV420 RT format not found");181}182183static cv::UMat readImage(const char* fileName)184{185cv::Mat m = cv::imread(fileName);186if (m.empty())187throw std::runtime_error("Failed to load image: " + std::string(fileName));188return m.getUMat(cv::ACCESS_RW);189}190191static void writeImage(const cv::UMat& u, const char* fileName, bool doInterop)192{193std::string fn = std::string(fileName) + std::string(doInterop ? ".on" : ".off") + std::string(".jpg");194cv::imwrite(fn, u);195}196197static float run(const char* infile, const char* outfile1, const char* outfile2, bool doInterop)198{199VASurfaceID surface;200VAStatus status;201Timer t;202203// initialize CL context for CL/VA interop204cv::va_intel::ocl::initializeContextFromVA(va::display, doInterop);205206// load input image207cv::UMat u1 = readImage(infile);208cv::Size size2 = u1.size();209status = vaCreateSurfaces(va::display, VA_RT_FORMAT_YUV420, size2.width, size2.height, &surface, 1, NULL, 0);210CHECK_VASTATUS(status, "vaCreateSurfaces");211212// transfer image into VA surface, make sure all CL initialization is done (kernels etc)213cv::va_intel::convertToVASurface(va::display, u1, surface, size2);214cv::va_intel::convertFromVASurface(va::display, surface, size2, u1);215cv::UMat u2;216cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3));217218// measure performance on some image processing219writeImage(u1, outfile1, doInterop);220t.start();221cv::va_intel::convertFromVASurface(va::display, surface, size2, u1);222cv::blur(u1, u2, cv::Size(7, 7), cv::Point(-3, -3));223cv::va_intel::convertToVASurface(va::display, u2, surface, size2);224t.stop();225writeImage(u2, outfile2, doInterop);226227vaDestroySurfaces(va::display, &surface,1);228229return t.time(Timer::MSEC);230}231232int main(int argc, char** argv)233{234try235{236CmdlineParser cmd(argc, argv);237if (!cmd.run())238{239cmd.usage();240return 0;241}242243if (!va::openDisplay())244throw std::runtime_error("Failed to open VA display for CL-VA interoperability");245std::cout << "VA display opened successfully" << std::endl;246247checkIfAvailableYUV420();248249const char* infile = cmd.getFile(CmdlineParser::fnInput);250const char* outfile1 = cmd.getFile(CmdlineParser::fnOutput1);251const char* outfile2 = cmd.getFile(CmdlineParser::fnOutput2);252bool doInterop = cmd.isInterop();253254float time = run(infile, outfile1, outfile2, doInterop);255256std::cout << "Interop " << (doInterop ? "ON " : "OFF") << ": processing time, msec: " << time << std::endl;257}258catch (std::exception& ex)259{260std::cerr << "ERROR: " << ex.what() << std::endl;261}262263va::closeDisplay();264return 0;265}266267268