blob: db440c70c73c993649206d5b8bb926a24ed6eaf1 [file] [log] [blame]
Wind Yuan75564b12015-01-15 06:51:15 -05001/*
2 * main.cpp - test
3 *
4 * Copyright (c) 2014 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21#include "device_manager.h"
22#include "atomisp_device.h"
23#include "isp_controller.h"
24#include "isp_image_processor.h"
25#include "x3a_analyzer_simple.h"
26#if HAVE_IA_AIQ
27#include "x3a_analyzer_aiq.h"
28#endif
Wind Yuand4427312015-02-11 16:09:00 +080029#if HAVE_LIBCL
Wind Yuane4ba0c92015-03-26 16:59:06 +080030#include "cl_3a_image_processor.h"
31#endif
32#if HAVE_LIBDRM
33#include "drm_display.h"
Wind Yuand4427312015-02-11 16:09:00 +080034#endif
35
Wind Yuan75564b12015-01-15 06:51:15 -050036#include <unistd.h>
37#include <signal.h>
38#include <stdlib.h>
ShincyTue521cf92015-03-27 15:13:51 +080039#include <string>
John Yeae9da732015-01-22 13:36:36 +080040#include "test_common.h"
41
Wind Yuan75564b12015-01-15 06:51:15 -050042using namespace XCam;
43
ShincyTue521cf92015-03-27 15:13:51 +080044static Mutex g_mutex;
45static Cond g_cond;
46static bool g_stop = false;
47
Wind Yuan75564b12015-01-15 06:51:15 -050048class MainDeviceManager
49 : public DeviceManager
50{
51public:
52 MainDeviceManager ()
53 : _file (NULL)
54 , _save_file (false)
55 , _interval (1)
56 , _frame_count (0)
ShincyTue521cf92015-03-27 15:13:51 +080057 , _frame_save (0)
Wind Yuan683f8662015-03-27 18:52:38 +080058 , _enable_display (false)
Wind Yuane4ba0c92015-03-26 16:59:06 +080059 {
60#if HAVE_LIBDRM
61 _display = DrmDisplay::instance();
62#endif
63 }
Wind Yuan75564b12015-01-15 06:51:15 -050064
65 ~MainDeviceManager () {
66 close_file ();
67 }
68
69 void enable_save_file (bool enable) {
70 _save_file = enable;
71 }
72 void set_interval (uint32_t inteval) {
73 _interval = inteval;
74 }
ShincyTue521cf92015-03-27 15:13:51 +080075 void set_frame_save (uint32_t frame_save) {
76 _frame_save = frame_save;
77 }
Wind Yuan75564b12015-01-15 06:51:15 -050078
Wind Yuan683f8662015-03-27 18:52:38 +080079 void enable_display(bool value) {
80 _enable_display = value;
81 }
82
Wind Yuan75564b12015-01-15 06:51:15 -050083protected:
84 virtual void handle_message (SmartPtr<XCamMessage> &msg);
85 virtual void handle_buffer (SmartPtr<VideoBuffer> &buf);
86
Wind Yuane4ba0c92015-03-26 16:59:06 +080087 int display_buf (SmartPtr<VideoBuffer> &buf);
88
Wind Yuan75564b12015-01-15 06:51:15 -050089private:
90 void open_file ();
91 void close_file ();
92
93 FILE *_file;
94 bool _save_file;
95 uint32_t _interval;
96 uint32_t _frame_count;
ShincyTue521cf92015-03-27 15:13:51 +080097 uint32_t _frame_save;
Wind Yuane4ba0c92015-03-26 16:59:06 +080098 SmartPtr<DrmDisplay> _display;
Wind Yuan683f8662015-03-27 18:52:38 +080099 bool _enable_display;
Wind Yuan75564b12015-01-15 06:51:15 -0500100};
101
102void
103MainDeviceManager::handle_message (SmartPtr<XCamMessage> &msg)
104{
105 XCAM_UNUSED (msg);
106}
107
108void
109MainDeviceManager::handle_buffer (SmartPtr<VideoBuffer> &buf)
110{
Wind Yuan683f8662015-03-27 18:52:38 +0800111 FPS_CALCULATION (fps_buf, 30);
112
113 if (_enable_display)
114 display_buf (buf);
Wind Yuane4ba0c92015-03-26 16:59:06 +0800115
Wind Yuan75564b12015-01-15 06:51:15 -0500116 if (!_save_file)
117 return ;
118
119 if ((_frame_count++ % _interval) != 0)
120 return;
121
ShincyTue521cf92015-03-27 15:13:51 +0800122 if ((_frame_save != 0) && (_frame_count > _frame_save)) {
123 SmartLock locker (g_mutex);
124 g_stop = true;
125 g_cond.broadcast ();
126 return;
127 }
128
Wind Yuan75564b12015-01-15 06:51:15 -0500129 const VideoBufferInfo & frame_info = buf->get_video_info ();
130 uint8_t *frame = buf->map ();
ShincyTu2808b592015-03-13 17:17:25 +0800131
Wind Yuan75564b12015-01-15 06:51:15 -0500132 if (frame == NULL)
133 return;
ShincyTu2808b592015-03-13 17:17:25 +0800134
135 uint32_t size = 0;
136
137 switch(frame_info.format) {
138 case V4L2_PIX_FMT_NV12: // 420
139 case V4L2_PIX_FMT_NV21:
140 size = XCAM_ALIGN_UP(frame_info.width, 2) * XCAM_ALIGN_UP(frame_info.height, 2) * 3 / 2;
141 break;
142 case V4L2_PIX_FMT_YUV422P: // 422 Planar
143 case V4L2_PIX_FMT_YUYV: // 422
144 case V4L2_PIX_FMT_SBGGR10:
145 case V4L2_PIX_FMT_SGBRG10:
146 case V4L2_PIX_FMT_SGRBG10:
147 case V4L2_PIX_FMT_SRGGB10:
148 size = XCAM_ALIGN_UP(frame_info.width, 2) * XCAM_ALIGN_UP(frame_info.height, 2) * 2;
149 break;
150 default:
151 XCAM_LOG_ERROR (
152 "unknown v4l2 format(%s) in buffer handle",
153 xcam_fourcc_to_string (frame_info.format));
154 return;
155 }
156
Wind Yuan75564b12015-01-15 06:51:15 -0500157 open_file ();
158 if (fwrite (frame, size, 1, _file) <= 0) {
159 XCAM_LOG_WARNING ("write frame failed.");
160 }
161}
162
Wind Yuane4ba0c92015-03-26 16:59:06 +0800163int
164MainDeviceManager::display_buf (SmartPtr<VideoBuffer> &buf)
165{
166#if HAVE_LIBDRM
167 XCamReturn ret = XCAM_RETURN_NO_ERROR;
168 const VideoBufferInfo & frame_info = buf->get_video_info ();
169 struct v4l2_rect rect = { 0, 0, (int)frame_info.width, (int)frame_info.height };
170
171 if (!_display->is_render_inited ()) {
Wind Yuan024e1f32015-03-30 16:27:41 +0800172 ret = _display->render_init (12, 3, 1920, 1080, frame_info.format, &rect);
Wind Yuane4ba0c92015-03-26 16:59:06 +0800173 CHECK (ret, "display failed on render_init");
174 }
175 ret = _display->render_setup_frame_buffer (buf);
176 CHECK (ret, "display failed on framebuf set");
177 ret = _display->render_buffer (buf);
178 CHECK (ret, "display failed on rendering");
179#endif
180 return 0;
181}
182
183
Wind Yuan75564b12015-01-15 06:51:15 -0500184void
185MainDeviceManager::open_file ()
186{
ShincyTue521cf92015-03-27 15:13:51 +0800187 if ((_file) && (_frame_save == 0))
Wind Yuan75564b12015-01-15 06:51:15 -0500188 return;
ShincyTue521cf92015-03-27 15:13:51 +0800189
190 std::string file_name = DEFAULT_SAVE_FILE_NAME;
191
192 if (_frame_save != 0) {
193 file_name += std::to_string(_frame_count);
194 }
195 file_name += ".raw";
196
197 _file = fopen(file_name.c_str(), "wb");
Wind Yuan75564b12015-01-15 06:51:15 -0500198}
199
200void
201MainDeviceManager::close_file ()
202{
203 if (_file)
204 fclose (_file);
205 _file = NULL;
206}
207
208#define V4L2_CAPTURE_MODE_STILL 0x2000
209#define V4L2_CAPTURE_MODE_VIDEO 0x4000
210#define V4L2_CAPTURE_MODE_PREVIEW 0x8000
211
Wind Yuan75564b12015-01-15 06:51:15 -0500212void dev_stop_handler(int sig)
213{
214 XCAM_UNUSED (sig);
215
216 SmartLock locker (g_mutex);
217 g_stop = true;
218 g_cond.broadcast ();
219
220 //exit(0);
221}
222
223void print_help (const char *bin_name)
224{
225 printf ("Usage: %s [-a analyzer]\n"
ShincyTue521cf92015-03-27 15:13:51 +0800226 "\t -a analyzer specify a analyzer\n"
227 "\t select from [simple, aiq], default is [simple]\n"
228 "\t -m mem_type specify video memory type\n"
229 "\t mem_type select from [dma, mmap], default is [mmap]\n"
230 "\t -s save file to %s\n"
231 "\t -n interval save file on every [interval] frame\n"
232 "\t -c process image with cl kernel\n"
233 "\t -f pixel_fmt specify output pixel format\n"
234 "\t pixel_fmt select from [NV12, YUYV, BA10], default is [NV12]\n"
235 "\t -d cap_mode specify capture mode\n"
236 "\t cap_mode select from [video, still], default is [video]\n"
237 "\t -i frame_save specify the frame count to save, default is 0 which means endless\n"
Wind Yuane4ba0c92015-03-26 16:59:06 +0800238 "\t -p preview on local display\n"
ShincyTue521cf92015-03-27 15:13:51 +0800239 "\t -h help\n"
Wind Yuan75564b12015-01-15 06:51:15 -0500240 , bin_name
241 , DEFAULT_SAVE_FILE_NAME);
242}
243
244int main (int argc, char *argv[])
245{
246 XCamReturn ret = XCAM_RETURN_NO_ERROR;
247 SmartPtr<MainDeviceManager> device_manager = new MainDeviceManager;
248 SmartPtr<V4l2Device> device;
249 SmartPtr<V4l2SubDevice> event_device;
250 SmartPtr<IspController> isp_controller;
251 SmartPtr<X3aAnalyzer> analyzer;
Wind Yuane4ba0c92015-03-26 16:59:06 +0800252 SmartPtr<ImageProcessor> isp_processor;
253#if HAVE_LIBDRM
254 SmartPtr<DrmDisplay> drm_disp = DrmDisplay::instance();
255#endif
256
Wind Yuand4427312015-02-11 16:09:00 +0800257#if HAVE_LIBCL
Wind Yuane4ba0c92015-03-26 16:59:06 +0800258 SmartPtr<CL3aImageProcessor> cl_processor;
Wind Yuand4427312015-02-11 16:09:00 +0800259#endif
260 bool have_cl_processor = false;
Wind Yuane4ba0c92015-03-26 16:59:06 +0800261 bool need_display = false;
Wind Yuand4427312015-02-11 16:09:00 +0800262 enum v4l2_memory v4l2_mem_type = V4L2_MEMORY_MMAP;
Wind Yuan75564b12015-01-15 06:51:15 -0500263 const char *bin_name = argv[0];
264 int opt;
ShincyTu2808b592015-03-13 17:17:25 +0800265 uint32_t capture_mode = V4L2_CAPTURE_MODE_VIDEO;
266 uint32_t pixel_format = V4L2_PIX_FMT_NV12;
Wind Yuan75564b12015-01-15 06:51:15 -0500267
ShincyTue521cf92015-03-27 15:13:51 +0800268 while ((opt = getopt(argc, argv, "sca:n:m:f:d:pi:h")) != -1) {
Wind Yuan75564b12015-01-15 06:51:15 -0500269 switch (opt) {
270 case 'a': {
271 if (!strcmp (optarg, "simple"))
272 analyzer = new X3aAnalyzerSimple ();
273#if HAVE_IA_AIQ
274 else if (!strcmp (optarg, "aiq"))
275 analyzer = new X3aAnalyzerAiq (isp_controller, DEFAULT_CPF_FILE);
276#endif
277 else {
278 print_help (bin_name);
279 return -1;
280 }
281 break;
282 }
283
Wind Yuand4427312015-02-11 16:09:00 +0800284 case 'm': {
285 if (!strcmp (optarg, "dma"))
286 v4l2_mem_type = V4L2_MEMORY_DMABUF;
287 else if (!strcmp (optarg, "mmap"))
288 v4l2_mem_type = V4L2_MEMORY_MMAP;
289 else
290 print_help (bin_name);
291 break;
292 }
293
Wind Yuan75564b12015-01-15 06:51:15 -0500294 case 's':
295 device_manager->enable_save_file (true);
296 break;
297 case 'n':
298 device_manager->set_interval (atoi(optarg));
299 break;
Wind Yuand4427312015-02-11 16:09:00 +0800300 case 'c':
301 have_cl_processor = true;
302 break;
ShincyTu2808b592015-03-13 17:17:25 +0800303 case 'f':
ShincyTuc8466402015-03-31 11:03:39 +0800304 CHECK_EXP ((strlen(optarg) == 4), "invalid pixel format\n");
305 pixel_format = v4l2_fourcc ((unsigned)optarg[0],
306 (unsigned)optarg[1],
307 (unsigned)optarg[2],
308 (unsigned)optarg[3]);
ShincyTu2808b592015-03-13 17:17:25 +0800309 break;
310 case 'd':
311 if (!strcmp (optarg, "still"))
312 capture_mode = V4L2_CAPTURE_MODE_STILL;
313 else if (!strcmp (optarg, "video"))
314 capture_mode = V4L2_CAPTURE_MODE_VIDEO;
315 else {
316 print_help (bin_name);
317 return -1;
318 }
319 break;
Wind Yuane4ba0c92015-03-26 16:59:06 +0800320 case 'p':
321 need_display = true;
322 break;
ShincyTue521cf92015-03-27 15:13:51 +0800323 case 'i':
324 device_manager->set_frame_save(atoi(optarg));
325 break;
Wind Yuan75564b12015-01-15 06:51:15 -0500326 case 'h':
327 print_help (bin_name);
328 return 0;
329
330 default:
331 print_help (bin_name);
332 return -1;
333 }
334 }
335
Wind Yuan683f8662015-03-27 18:52:38 +0800336 if (need_display)
337 device_manager->enable_display (true);
338
ShincyTu2808b592015-03-13 17:17:25 +0800339 if (!device.ptr ()) {
340 if (capture_mode == V4L2_CAPTURE_MODE_STILL)
341 device = new AtomispDevice (CAPTURE_DEVICE_STILL);
342 else if (capture_mode == V4L2_CAPTURE_MODE_VIDEO)
343 device = new AtomispDevice (CAPTURE_DEVICE_VIDEO);
344 else
345 device = new AtomispDevice (DEFAULT_CAPTURE_DEVICE);
346 }
Wind Yuan75564b12015-01-15 06:51:15 -0500347 if (!event_device.ptr ())
348 event_device = new V4l2SubDevice (DEFAULT_EVENT_DEVICE);
349 if (!isp_controller.ptr ())
350 isp_controller = new IspController (device);
Wind Yuane4ba0c92015-03-26 16:59:06 +0800351 if (!isp_processor.ptr ())
352 isp_processor = new IspImageProcessor (isp_controller);
Wind Yuan75564b12015-01-15 06:51:15 -0500353 //if (!analyzer.ptr())
354 // analyzer = new X3aAnalyzerSimple ();
355
356 signal(SIGINT, dev_stop_handler);
357
358 device->set_sensor_id (0);
ShincyTu2808b592015-03-13 17:17:25 +0800359 device->set_capture_mode (capture_mode);
Wind Yuan75564b12015-01-15 06:51:15 -0500360 //device->set_mem_type (V4L2_MEMORY_DMABUF);
Wind Yuand4427312015-02-11 16:09:00 +0800361 device->set_mem_type (v4l2_mem_type);
Wind Yuan75564b12015-01-15 06:51:15 -0500362 device->set_buffer_count (8);
363 device->set_framerate (25, 1);
364 ret = device->open ();
365 CHECK (ret, "device(%s) open failed", device->get_device_name());
ShincyTu2808b592015-03-13 17:17:25 +0800366 ret = device->set_format (1920, 1080, pixel_format, V4L2_FIELD_NONE, 1920 * 2);
Wind Yuan75564b12015-01-15 06:51:15 -0500367 CHECK (ret, "device(%s) set format failed", device->get_device_name());
368
369 ret = event_device->open ();
370 CHECK (ret, "event device(%s) open failed", event_device->get_device_name());
371 int event = V4L2_EVENT_ATOMISP_3A_STATS_READY;
372 ret = event_device->subscribe_event (event);
373 CHECK_CONTINUE (
374 ret,
375 "device(%s) subscribe event(%d) failed",
376 event_device->get_device_name(), event);
377 event = V4L2_EVENT_FRAME_SYNC;
378 ret = event_device->subscribe_event (event);
379 CHECK_CONTINUE (
380 ret,
381 "device(%s) subscribe event(%d) failed",
382 event_device->get_device_name(), event);
383
384 device_manager->set_capture_device (device);
385 device_manager->set_event_device (event_device);
386 device_manager->set_isp_controller (isp_controller);
387 if (analyzer.ptr())
388 device_manager->set_analyzer (analyzer);
Wind Yuane4ba0c92015-03-26 16:59:06 +0800389 device_manager->add_image_processor (isp_processor);
Wind Yuand4427312015-02-11 16:09:00 +0800390#if HAVE_LIBCL
391 if (have_cl_processor) {
Wind Yuane4ba0c92015-03-26 16:59:06 +0800392 cl_processor = new CL3aImageProcessor ();
Wind Yuan7ddf2602015-04-14 18:49:45 +0800393 cl_processor->set_stats_callback(device_manager);
Wind Yuane4ba0c92015-03-26 16:59:06 +0800394 cl_processor->set_hdr (true);
Juan Zhaoab5e6fe2015-04-08 14:12:46 +0800395 cl_processor->set_denoise (false);
Wind Yuane4ba0c92015-03-26 16:59:06 +0800396 if (need_display) {
397 cl_processor->set_output_format (V4L2_PIX_FMT_XBGR32);
398 }
Wind Yuand4427312015-02-11 16:09:00 +0800399 device_manager->add_image_processor (cl_processor);
400 }
401#endif
Wind Yuane4ba0c92015-03-26 16:59:06 +0800402
Wind Yuan75564b12015-01-15 06:51:15 -0500403 ret = device_manager->start ();
404 CHECK (ret, "device manager start failed");
405
406 // wait for interruption
407 {
408 SmartLock locker (g_mutex);
409 while (!g_stop)
410 g_cond.wait (g_mutex);
411 }
412
413 ret = device_manager->stop();
414 CHECK_CONTINUE (ret, "device manager stop failed");
415 device->close ();
416 event_device->close ();
417
418 return 0;
419}