parent
e657896a7c
commit
f4b8f9ec84
12 changed files with 261 additions and 506 deletions
@ -1,46 +0,0 @@ |
|||||||
TARGET := video-demo2
|
|
||||||
|
|
||||||
SRCS := video-demo2.cpp
|
|
||||||
|
|
||||||
#precompiled headers
|
|
||||||
HEADERS :=
|
|
||||||
OBJS := ${SRCS:.cpp=.o}
|
|
||||||
DEPS := ${SRCS:.cpp=.dep}
|
|
||||||
|
|
||||||
CXXFLAGS += -fpic
|
|
||||||
LDFLAGS +=
|
|
||||||
LIBS += -lm
|
|
||||||
.PHONY: all release debug clean distclean |
|
||||||
|
|
||||||
all: release |
|
||||||
release: ${TARGET} |
|
||||||
debug: ${TARGET} |
|
||||||
info: ${TARGET} |
|
||||||
profile: ${TARGET} |
|
||||||
unsafe: ${TARGET} |
|
||||||
asan: ${TARGET} |
|
||||||
|
|
||||||
${TARGET}: ${OBJS} |
|
||||||
${CXX} ${LDFLAGS} -o $@ $^ ${LIBS}
|
|
||||||
|
|
||||||
${OBJS}: %.o: %.cpp %.dep ${GCH} |
|
||||||
${CXX} ${CXXFLAGS} -o $@ -c $<
|
|
||||||
|
|
||||||
${DEPS}: %.dep: %.cpp Makefile |
|
||||||
${CXX} ${CXXFLAGS} -MM $< > $@
|
|
||||||
|
|
||||||
${GCH}: %.gch: ${HEADERS} |
|
||||||
${CXX} ${CXXFLAGS} -o $@ -c ${@:.gch=.hpp}
|
|
||||||
|
|
||||||
install: |
|
||||||
mkdir -p ${DESTDIR}/${PREFIX}
|
|
||||||
cp ${TARGET} ${DESTDIR}/${PREFIX}
|
|
||||||
|
|
||||||
uninstall: |
|
||||||
rm ${DESTDIR}/${PREFIX}/${TARGET}
|
|
||||||
|
|
||||||
clean: |
|
||||||
rm -f *~ ${DEPS} ${OBJS} ${CUO} ${GCH} ${TARGET}
|
|
||||||
|
|
||||||
distclean: clean |
|
||||||
|
|
@ -1,159 +0,0 @@ |
|||||||
#define CL_TARGET_OPENCL_VERSION 120 |
|
||||||
|
|
||||||
#include "../common/subsystems.hpp" |
|
||||||
#include <string> |
|
||||||
|
|
||||||
constexpr long unsigned int WIDTH = 1920; |
|
||||||
constexpr long unsigned int HEIGHT = 1080; |
|
||||||
constexpr const int VA_HW_DEVICE_INDEX = 0; |
|
||||||
constexpr bool OFFSCREEN = true; |
|
||||||
constexpr const char* OUTPUT_FILENAME = "video-demo.mkv"; |
|
||||||
constexpr unsigned long DIAG = hypot(double(WIDTH), double(HEIGHT)); |
|
||||||
|
|
||||||
constexpr int GLOW_KERNEL_SIZE = std::max(int(DIAG / 138 % 2 == 0 ? DIAG / 138 + 1 : DIAG / 138), 1); |
|
||||||
|
|
||||||
using std::cerr; |
|
||||||
using std::endl; |
|
||||||
using std::string; |
|
||||||
|
|
||||||
void init_scene(unsigned long w, unsigned long h) { |
|
||||||
//Initialize the OpenGL scene
|
|
||||||
glViewport(0, 0, w, h); |
|
||||||
glColor3f(1.0, 1.0, 1.0); |
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE); |
|
||||||
glCullFace(GL_BACK); |
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION); |
|
||||||
glLoadIdentity(); |
|
||||||
glFrustum(-2, 2, -1.5, 1.5, 1, 40); |
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW); |
|
||||||
glLoadIdentity(); |
|
||||||
glTranslatef(0, 0, -3); |
|
||||||
glRotatef(50, 1, 0, 0); |
|
||||||
glRotatef(70, 0, 1, 0); |
|
||||||
} |
|
||||||
|
|
||||||
void render_scene(unsigned long w, unsigned long h) { |
|
||||||
//Render a tetrahedron using immediate mode because the code is more concise for a demo
|
|
||||||
glViewport(0, 0, w, h); |
|
||||||
glRotatef(1, 0, 1, 0); |
|
||||||
glClearColor(0.0f, 0.0f, 1.0f, 1.0f); |
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_STRIP); |
|
||||||
glColor3f(1, 1, 1); |
|
||||||
glVertex3f(0, 2, 0); |
|
||||||
glColor3f(1, 0, 0); |
|
||||||
glVertex3f(-1, 0, 1); |
|
||||||
glColor3f(0, 1, 0); |
|
||||||
glVertex3f(1, 0, 1); |
|
||||||
glColor3f(0, 0, 1); |
|
||||||
glVertex3f(0, 0, -1.4); |
|
||||||
glColor3f(1, 1, 1); |
|
||||||
glVertex3f(0, 2, 0); |
|
||||||
glColor3f(1, 0, 0); |
|
||||||
glVertex3f(-1, 0, 1); |
|
||||||
glEnd(); |
|
||||||
} |
|
||||||
|
|
||||||
void glow_effect(const cv::UMat &src, cv::UMat &dst, const int ksize) { |
|
||||||
static cv::UMat resize; |
|
||||||
static cv::UMat blur; |
|
||||||
static cv::UMat dst16; |
|
||||||
|
|
||||||
cv::bitwise_not(src, dst); |
|
||||||
|
|
||||||
//Resize for some extra performance
|
|
||||||
cv::resize(dst, resize, cv::Size(), 0.5, 0.5); |
|
||||||
//Cheap blur
|
|
||||||
cv::boxFilter(resize, resize, -1, cv::Size(ksize, ksize), cv::Point(-1,-1), true, cv::BORDER_REPLICATE); |
|
||||||
//Back to original size
|
|
||||||
cv::resize(resize, blur, src.size()); |
|
||||||
|
|
||||||
//Multiply the src image with a blurred version of itself
|
|
||||||
cv::multiply(dst, blur, dst16, 1, CV_16U); |
|
||||||
//Normalize and convert back to CV_8U
|
|
||||||
cv::divide(dst16, cv::Scalar::all(255.0), dst, 1, CV_8U); |
|
||||||
|
|
||||||
cv::bitwise_not(dst, dst); |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char **argv) { |
|
||||||
using namespace kb; |
|
||||||
|
|
||||||
if(argc != 2) { |
|
||||||
cerr << "Usage: video-demo <video-file>" << endl; |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
|
|
||||||
//Initialize the application
|
|
||||||
app::init("Video Demo", WIDTH, HEIGHT, OFFSCREEN); |
|
||||||
//Print system information
|
|
||||||
app::print_system_info(); |
|
||||||
|
|
||||||
//Initialize MJPEG HW decoding using VAAPI
|
|
||||||
cv::VideoCapture capture(argv[1], cv::CAP_FFMPEG, { |
|
||||||
cv::CAP_PROP_HW_DEVICE, VA_HW_DEVICE_INDEX, |
|
||||||
cv::CAP_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_VAAPI, |
|
||||||
cv::CAP_PROP_HW_ACCELERATION_USE_OPENCL, 1 |
|
||||||
}); |
|
||||||
|
|
||||||
//Copy OpenCL Context for VAAPI. Must be called right after first VideoWriter/VideoCapture initialization.
|
|
||||||
va::copy(); |
|
||||||
|
|
||||||
if (!capture.isOpened()) { |
|
||||||
cerr << "ERROR! Unable to open video input" << endl; |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
double fps = capture.get(cv::CAP_PROP_FPS); |
|
||||||
|
|
||||||
//Initialize VP9 HW encoding using VAAPI. We don't need to specify the hardware device twice. only generates a warning.
|
|
||||||
cv::VideoWriter writer(OUTPUT_FILENAME, cv::CAP_FFMPEG, cv::VideoWriter::fourcc('V', 'P', '9', '0'), fps, cv::Size(WIDTH, HEIGHT), { |
|
||||||
cv::VIDEOWRITER_PROP_HW_ACCELERATION, cv::VIDEO_ACCELERATION_VAAPI, |
|
||||||
cv::VIDEOWRITER_PROP_HW_ACCELERATION_USE_OPENCL, 1 |
|
||||||
}); |
|
||||||
|
|
||||||
gl::render([WIDTH, HEIGHT]() { |
|
||||||
init_scene(WIDTH, HEIGHT); |
|
||||||
}); |
|
||||||
|
|
||||||
while (true) { |
|
||||||
va::read([&capture](cv::UMat& videoFrame){ |
|
||||||
//videoFrame will be converted to BGRA and stored in the frameBuffer.
|
|
||||||
capture >> videoFrame; |
|
||||||
assert(!videoFrame.empty()); |
|
||||||
}); |
|
||||||
|
|
||||||
cl::work([](cv::UMat& frameBuffer){ |
|
||||||
//Resize the frame if necessary. (OpenCL)
|
|
||||||
cv::resize(frameBuffer, frameBuffer, cv::Size(WIDTH, HEIGHT)); |
|
||||||
}); |
|
||||||
|
|
||||||
gl::render([&WIDTH, &HEIGHT]() { |
|
||||||
//Render using OpenGL
|
|
||||||
render_scene(WIDTH, HEIGHT); |
|
||||||
}); |
|
||||||
|
|
||||||
cl::work([&GLOW_KERNEL_SIZE](cv::UMat& frameBuffer){ |
|
||||||
//Glow effect (OpenCL)
|
|
||||||
glow_effect(frameBuffer, frameBuffer, GLOW_KERNEL_SIZE); |
|
||||||
}); |
|
||||||
|
|
||||||
//If onscreen rendering is enabled it displays the framebuffer in the native window. Returns false if the window was closed.
|
|
||||||
if(!app::display()) |
|
||||||
break; |
|
||||||
|
|
||||||
va::write([&writer](const cv::UMat& videoFrame){ |
|
||||||
//videoFrame is the frameBuffer converted to BGR. Ready to be written.
|
|
||||||
writer << videoFrame; |
|
||||||
}); |
|
||||||
|
|
||||||
app::print_fps(); |
|
||||||
} |
|
||||||
|
|
||||||
app::terminate(); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
Loading…
Reference in new issue