drm local preview: add primary plane and page flip mode to improve
stability and display fps. Primary mode as default display mode, and
use cmd to point at overlay mode:
./test-device-manager -f YUYV -m dma -d video -e overlay -p
diff --git a/cl_kernel/kernel_csc_yuyvtorgba.cl b/cl_kernel/kernel_csc_yuyvtorgba.cl
new file mode 100644
index 0000000..9531ae8
--- /dev/null
+++ b/cl_kernel/kernel_csc_yuyvtorgba.cl
@@ -0,0 +1,25 @@
+/*
+ * function: kernel_csc_yuyvtorgba
+ * input: image2d_t as read only
+ * output: image2d_t as write only
+ */
+
+"__kernel void kernel_csc_yuyvtorgba (__read_only image2d_t input, __write_only image2d_t output) "
+"{ "
+" int x = get_global_id (0); "
+" int y = get_global_id (1); "
+" sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE | CLK_FILTER_NEAREST; "
+" float4 pixel_in1 = read_imagef(input, sampler, (int2)(x,y)); "
+" float4 pixel_out1,pixel_out2; "
+" pixel_out1.x = pixel_in1.x + 1.13983 * (pixel_in1.w - 0.5); "
+" pixel_out1.y = pixel_in1.x - 0.39465 * (pixel_in1.y - 0.5) - 0.5806 * (pixel_in1.w - 0.5); "
+" pixel_out1.z = pixel_in1.x + 2.03211 * (pixel_in1.y - 0.5); "
+" pixel_out1.w = 0.0; "
+" pixel_out2.x = pixel_in1.z + 1.13983 * (pixel_in1.w - 0.5); "
+" pixel_out2.y = pixel_in1.z - 0.39465 * (pixel_in1.y - 0.5) - 0.5806 * (pixel_in1.w - 0.5); "
+" pixel_out2.z = pixel_in1.z + 2.03211 * (pixel_in1.y - 0.5); "
+" pixel_out2.w = 0.0; "
+" write_imagef(output, (int2)(2*x,y), pixel_out1); "
+" write_imagef(output, (int2)(2*x+1,y), pixel_out2); "
+"} "
+
diff --git a/tests/test-device-manager.cpp b/tests/test-device-manager.cpp
index 25b4f5c..51f1260 100644
--- a/tests/test-device-manager.cpp
+++ b/tests/test-device-manager.cpp
@@ -28,6 +28,7 @@
#endif
#if HAVE_LIBCL
#include "cl_3a_image_processor.h"
+#include "cl_csc_image_processor.h"
#endif
#if HAVE_LIBDRM
#include "drm_display.h"
@@ -81,6 +82,10 @@
_enable_display = value;
}
+ void set_display_mode(DrmDisplayMode mode) {
+ _display->set_display_mode (mode);
+ }
+
protected:
virtual void handle_message (SmartPtr<XCamMessage> &msg);
virtual void handle_buffer (SmartPtr<VideoBuffer> &buf);
@@ -242,7 +247,9 @@
"\t -d cap_mode specify capture mode\n"
"\t cap_mode select from [video, still], default is [video]\n"
"\t -i frame_save specify the frame count to save, default is 0 which means endless\n"
- "\t -p preview on local display\n"
+ "\t -p preview on local display\n"
+ "\t -e display_mode preview mode\n"
+ "\t select from [primary, overlay], default is [primary]\n"
"\t -h help\n"
, bin_name
, DEFAULT_SAVE_FILE_NAME);
@@ -257,7 +264,9 @@
SmartPtr<IspController> isp_controller;
SmartPtr<X3aAnalyzer> analyzer;
SmartPtr<ImageProcessor> isp_processor;
+ SmartPtr<CLCscImageProcessor> cl_csc_proccessor;
AnalyzerType analyzer_type = AnalyzerTypeSimple;
+ DrmDisplayMode display_mode = DRM_DISPLAY_MODE_PRIMARY;
#if HAVE_LIBDRM
SmartPtr<DrmDisplay> drm_disp = DrmDisplay::instance();
#endif
@@ -273,7 +282,7 @@
uint32_t capture_mode = V4L2_CAPTURE_MODE_VIDEO;
uint32_t pixel_format = V4L2_PIX_FMT_NV12;
- while ((opt = getopt(argc, argv, "sca:n:m:f:d:pi:h")) != -1) {
+ while ((opt = getopt(argc, argv, "sca:n:m:f:d:pi:e:h")) != -1) {
switch (opt) {
case 'a': {
if (!strcmp (optarg, "dynamic"))
@@ -330,6 +339,17 @@
case 'p':
need_display = true;
break;
+ case 'e': {
+ if (!strcmp (optarg, "primary"))
+ display_mode = DRM_DISPLAY_MODE_PRIMARY;
+ else if (!strcmp (optarg, "overlay"))
+ display_mode = DRM_DISPLAY_MODE_OVERLAY;
+ else {
+ print_help (bin_name);
+ return -1;
+ }
+ break;
+ }
case 'i':
device_manager->set_frame_save(atoi(optarg));
break;
@@ -343,9 +363,10 @@
}
}
- if (need_display)
+ if (need_display) {
device_manager->enable_display (true);
-
+ device_manager->set_display_mode (display_mode);
+ }
if (!device.ptr ()) {
if (capture_mode == V4L2_CAPTURE_MODE_STILL)
device = new AtomispDevice (CAPTURE_DEVICE_STILL);
@@ -421,6 +442,11 @@
XCAM_ASSERT (isp_processor.ptr ());
device_manager->add_image_processor (isp_processor);
+ if ((display_mode == DRM_DISPLAY_MODE_PRIMARY) && need_display && (!have_cl_processor)) {
+ cl_csc_proccessor = new CLCscImageProcessor();
+ XCAM_ASSERT (cl_csc_proccessor.ptr ());
+ device_manager->add_image_processor (cl_csc_proccessor);
+ }
#if HAVE_LIBCL
if (have_cl_processor) {
diff --git a/xcore/Makefile.am b/xcore/Makefile.am
index 722a371..38f0188 100644
--- a/xcore/Makefile.am
+++ b/xcore/Makefile.am
@@ -104,6 +104,7 @@
cl_image_handler.cpp \
cl_image_processor.cpp \
cl_3a_image_processor.cpp \
+ cl_csc_image_processor.cpp \
cl_3a_stats_calculator.cpp \
cl_demo_handler.cpp \
cl_blc_handler.cpp \
diff --git a/xcore/cl_csc_handler.cpp b/xcore/cl_csc_handler.cpp
index aab7533..765687d 100644
--- a/xcore/cl_csc_handler.cpp
+++ b/xcore/cl_csc_handler.cpp
@@ -78,7 +78,9 @@
work_size.global[1] = video_info.height / 2;
arg_count = 4;
}
- else if ((video_info.format == XCAM_PIX_FMT_LAB) || (video_info.format == V4L2_PIX_FMT_RGBA32)) {
+ else if ((video_info.format == XCAM_PIX_FMT_LAB)
+ || (video_info.format == V4L2_PIX_FMT_RGBA32)
+ || (video_info.format == V4L2_PIX_FMT_YUYV)) {
work_size.global[0] = video_info.width;
work_size.global[1] = video_info.height;
arg_count = 2;
@@ -102,6 +104,7 @@
_output_format = XCAM_PIX_FMT_LAB;
break;
case CL_CSC_TYPE_RGBA64TORGBA:
+ case CL_CSC_TYPE_YUYVTORGBA:
_output_format = V4L2_PIX_FMT_RGBA32;
break;
default:
@@ -165,6 +168,10 @@
#include "kernel_csc_rgba64torgba.cl"
XCAM_CL_KERNEL_FUNC_END;
+ XCAM_CL_KERNEL_FUNC_SOURCE_BEGIN(kernel_csc_yuyvtorgba)
+#include "kernel_csc_yuyvtorgba.cl"
+ XCAM_CL_KERNEL_FUNC_END;
+
if (type == CL_CSC_TYPE_RGBATONV12) {
csc_kernel = new CLCscImageKernel (context, "kernel_csc_rgbatonv12");
@@ -178,6 +185,10 @@
csc_kernel = new CLCscImageKernel (context, "kernel_csc_rgba64torgba");
ret = csc_kernel->load_from_source (kernel_csc_rgba64torgba_body, strlen (kernel_csc_rgba64torgba_body));
}
+ else if (type == CL_CSC_TYPE_YUYVTORGBA) {
+ csc_kernel = new CLCscImageKernel (context, "kernel_csc_yuyvtorgba");
+ ret = csc_kernel->load_from_source (kernel_csc_yuyvtorgba_body, strlen (kernel_csc_yuyvtorgba_body));
+ }
XCAM_FAIL_RETURN (
WARNING,
diff --git a/xcore/cl_csc_handler.h b/xcore/cl_csc_handler.h
index b3dcfe9..98d8ae5 100644
--- a/xcore/cl_csc_handler.h
+++ b/xcore/cl_csc_handler.h
@@ -32,6 +32,7 @@
CL_CSC_TYPE_RGBATONV12,
CL_CSC_TYPE_RGBATOLAB,
CL_CSC_TYPE_RGBA64TORGBA,
+ CL_CSC_TYPE_YUYVTORGBA,
};
class CLCscImageKernel
diff --git a/xcore/cl_csc_image_processor.cpp b/xcore/cl_csc_image_processor.cpp
new file mode 100644
index 0000000..ee3bbf4
--- /dev/null
+++ b/xcore/cl_csc_image_processor.cpp
@@ -0,0 +1,58 @@
+/*
+ * cl_3a_image_processor.cpp - CL 3A image processor
+ *
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: wangfei <feix.w.wang@intel.com>
+ */
+#include "cl_csc_image_processor.h"
+#include "cl_context.h"
+#include "cl_csc_handler.h"
+
+
+namespace XCam {
+
+CLCscImageProcessor::CLCscImageProcessor ()
+ : CLImageProcessor ("CLCscImageProcessor")
+{
+ XCAM_LOG_DEBUG ("CLCscImageProcessor constructed");
+}
+
+CLCscImageProcessor::~CLCscImageProcessor ()
+{
+ XCAM_LOG_DEBUG ("CLCscImageProcessor destructed");
+}
+
+XCamReturn
+CLCscImageProcessor::create_handlers ()
+{
+ SmartPtr<CLImageHandler> image_handler;
+ SmartPtr<CLContext> context = get_cl_context ();
+
+ XCAM_ASSERT (context.ptr ());
+
+ /* color space conversion */
+ image_handler = create_cl_csc_image_handler (context, CL_CSC_TYPE_YUYVTORGBA);
+ _csc = image_handler.dynamic_cast_ptr<CLCscImageHandler> ();
+ XCAM_FAIL_RETURN (
+ WARNING,
+ _csc .ptr (),
+ XCAM_RETURN_ERROR_CL,
+ "CLCscImageProcessor create csc handler failed");
+ add_handler (image_handler);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/xcore/cl_csc_image_processor.h b/xcore/cl_csc_image_processor.h
new file mode 100644
index 0000000..f44fdab
--- /dev/null
+++ b/xcore/cl_csc_image_processor.h
@@ -0,0 +1,49 @@
+/*
+ * cl_3a_image_processor.h - CL 3A image processor
+ *
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: wangfei <feix.w.wang@intel.com>
+ */
+
+#ifndef XCAM_CL_CSC_IMAGE_PROCESSOR_H
+#define XCAM_CL_CSC_IMAGE_PROCESSOR_H
+
+#include "xcam_utils.h"
+#include "cl_image_processor.h"
+#include "stats_callback_interface.h"
+
+namespace XCam {
+
+class CLCscImageHandler;
+
+class CLCscImageProcessor
+ : public CLImageProcessor
+{
+
+public:
+ explicit CLCscImageProcessor ();
+ virtual ~CLCscImageProcessor ();
+
+private:
+ virtual XCamReturn create_handlers ();
+ XCAM_DEAD_COPY (CLCscImageProcessor);
+
+private:
+ SmartPtr<CLCscImageHandler> _csc;
+};
+
+};
+#endif //XCAM_CL_CSC_IMAGE_PROCESSOR_H
diff --git a/xcore/cl_image_processor.cpp b/xcore/cl_image_processor.cpp
index 83afbcd..c8f624e 100644
--- a/xcore/cl_image_processor.cpp
+++ b/xcore/cl_image_processor.cpp
@@ -24,6 +24,7 @@
#include "drm_display.h"
#include "cl_demo_handler.h"
#include "cl_blc_handler.h"
+#include "cl_csc_handler.h"
namespace XCam {
diff --git a/xcore/drm_display.cpp b/xcore/drm_display.cpp
index ff709ca..fffd280 100644
--- a/xcore/drm_display.cpp
+++ b/xcore/drm_display.cpp
@@ -48,6 +48,7 @@
: _module(NULL)
, _fd (-1)
, _buf_manager (NULL)
+ , _display_mode (DRM_DISPLAY_MODE_PRIMARY)
, _crtc_index (-1)
, _crtc_id (0)
, _con_id (0)
@@ -133,6 +134,7 @@
if(_connector->connection == DRM_MODE_CONNECTED) {
_con_id = res->connectors[i];
_encoder_id = res->encoders[i];
+ _mode = *_connector->modes;
}
drmModeFreeConnector(_connector);
}
@@ -227,8 +229,8 @@
"failed to get plane with required format %s", strerror(errno));
drmModeFreeResources(resource);
-
- _is_render_inited = true;
+ if (_display_mode == DRM_DISPLAY_MODE_OVERLAY)
+ _is_render_inited = true;
return XCAM_RETURN_NO_ERROR;
}
@@ -323,6 +325,23 @@
}
XCamReturn
+DrmDisplay::set_crtc (const FB &fb)
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ uint32_t fb_handle = fb.fb_handle;
+ //uint32_t index = fb.index;
+
+ if( !_is_render_inited) {
+ ret = (XCamReturn) drmModeSetCrtc(_fd, _crtc_id, fb_handle, 0,
+ 0, &_con_id, 1, &_mode);
+ XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, XCAM_RETURN_ERROR_IOCTL,
+ "failed to set crct via drm: %s", strerror(errno));
+ _is_render_inited = true;
+ }
+ return ret;
+}
+
+XCamReturn
DrmDisplay::set_plane (const FB &fb)
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
@@ -361,20 +380,37 @@
XCAM_FAIL_RETURN(ERROR, ret == XCAM_RETURN_NO_ERROR, XCAM_RETURN_ERROR_IOCTL,
"failed on page flip: %s", strerror(errno));
+ drmEventContext evctx;
+ struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
+ fd_set fds;
+ memset(&evctx, 0, sizeof evctx);
+ evctx.version = DRM_EVENT_CONTEXT_VERSION;
+ evctx.vblank_handler = NULL;
+ //evctx.page_flip_handler = page_flip_handler;
+ FD_ZERO(&fds);
+ FD_SET(_fd, &fds);
+ select(_fd + 1, &fds, NULL, NULL, &timeout);
+ drmHandleEvent(_fd, &evctx);
+
return XCAM_RETURN_NO_ERROR;
}
XCamReturn
DrmDisplay::render_buffer(SmartPtr<VideoBuffer> &buf)
{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
FBMap::iterator iter = _buf_fb_handles.find (buf.ptr ());
XCAM_FAIL_RETURN(
ERROR,
iter != _buf_fb_handles.end (),
XCAM_RETURN_ERROR_PARAM,
"buffer not register on framebuf");
-
- XCamReturn ret = _plane_id ? set_plane(iter->second) : page_flip(iter->second);
+ if(_display_mode == DRM_DISPLAY_MODE_OVERLAY)
+ ret = _plane_id ? set_plane(iter->second) : page_flip(iter->second);
+ else if(_display_mode == DRM_DISPLAY_MODE_PRIMARY) {
+ ret = set_crtc (iter->second);
+ ret = page_flip (iter->second);
+ }
_display_buf = buf;
return ret;
diff --git a/xcore/drm_display.h b/xcore/drm_display.h
index 609c4da..f0c2b2c 100644
--- a/xcore/drm_display.h
+++ b/xcore/drm_display.h
@@ -50,6 +50,12 @@
class DrmBoBufferPool;
class DrmBoBuffer;
+enum DrmDisplayMode {
+ DRM_DISPLAY_MODE_NONE = 0,
+ DRM_DISPLAY_MODE_PRIMARY,
+ DRM_DISPLAY_MODE_OVERLAY,
+};
+
class DrmDisplay {
friend class DrmBoBufferPool;
friend class CLBoBufferPool;
@@ -97,6 +103,11 @@
const enum v4l2_buf_type buf_type);
SmartPtr<DrmBoBuffer> convert_to_drm_bo_buf (SmartPtr<DrmDisplay> &self, SmartPtr<VideoBuffer> &buf_in);
+ bool set_display_mode(DrmDisplayMode mode) {
+ _display_mode = mode;
+ return true;
+ };
+
private:
DrmDisplay (const char* module = NULL);
@@ -107,6 +118,7 @@
XCamReturn get_connector(drmModeRes *res);
XCamReturn get_plane();
XCamReturn set_plane(const FB &fb);
+ XCamReturn set_crtc(const FB &fb);
XCamReturn page_flip(const FB &fb);
private:
@@ -115,12 +127,13 @@
char *_module;
int _fd;
drm_intel_bufmgr *_buf_manager;
-
+ DrmDisplayMode _display_mode;
int _crtc_index;
unsigned int _crtc_id;
unsigned int _con_id;
unsigned int _encoder_id;
unsigned int _plane_id;
+ drmModeModeInfo _mode;
drmModeConnector *_connector;
bool _is_render_inited;