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