XCamReturn V4l2Device::init_buffer_pool () { XCamReturn ret = XCAM_RETURN_NO_ERROR; uint32_t i = 0; _buf_pool.clear (); _buf_pool.reserve (_buf_count); for (; i < _buf_count; i++) { SmartPtr<V4l2Buffer> new_buf; ret = allocate_buffer (new_buf, _format, i); if (ret != XCAM_RETURN_NO_ERROR) { break; } _buf_pool.push_back (new_buf); } if (_buf_pool.empty()) { XCAM_LOG_ERROR ("No bufer allocated in device(%s)", XCAM_STR (_name)); return XCAM_RETURN_ERROR_MEM; } if (i != _buf_count) { XCAM_LOG_WARNING ( "device(%s) allocate buffer count:%d failback to %d", XCAM_STR (_name), _buf_count, i); _buf_count = i; } return XCAM_RETURN_NO_ERROR; }
XCamReturn V4l2Device::request_buffer () { struct v4l2_requestbuffers request_buf; XCAM_ASSERT (!is_activated()); xcam_mem_clear (request_buf); request_buf.type = _capture_buf_type; request_buf.count = _buf_count; request_buf.memory = _memory_type; if (io_control (VIDIOC_REQBUFS, &request_buf) < 0) { XCAM_LOG_INFO ("device(%s) starts failed on VIDIOC_REQBUFS", XCAM_STR (_name)); return XCAM_RETURN_ERROR_IOCTL; } if (request_buf.count != _buf_count) { XCAM_LOG_DEBUG ( "device(%s) request buffer count doesn't match user settings, reset buffer count to %d", XCAM_STR (_name), request_buf.count); _buf_count = request_buf.count; } return XCAM_RETURN_NO_ERROR; }
XCamReturn V4l2Device::dequeue_buffer(SmartPtr<V4l2Buffer> &buf) { struct v4l2_buffer v4l2_buf; if (!is_activated()) { XCAM_LOG_DEBUG ( "device(%s) dequeue buffer failed since not activated", XCAM_STR (_name)); return XCAM_RETURN_ERROR_PARAM; } xcam_mem_clear (v4l2_buf); v4l2_buf.type = _capture_buf_type; v4l2_buf.memory = _memory_type; if (this->io_control (VIDIOC_DQBUF, &v4l2_buf) < 0) { XCAM_LOG_ERROR ("device(%s) fail to dequeue buffer.", XCAM_STR (_name)); return XCAM_RETURN_ERROR_IOCTL; } XCAM_LOG_DEBUG ("device(%s) dequeue buffer index:%d", XCAM_STR (_name), v4l2_buf.index); if (v4l2_buf.index > _buf_count) { XCAM_LOG_ERROR ( "device(%s) dequeue wrong buffer index:%d", XCAM_STR (_name), v4l2_buf.index); return XCAM_RETURN_ERROR_ISP; } buf = _buf_pool [v4l2_buf.index]; buf->set_timestamp (v4l2_buf.timestamp); buf->set_timecode (v4l2_buf.timecode); buf->set_sequence (v4l2_buf.sequence); //buf.set_length (v4l2_buf.length); // not necessary to set length return XCAM_RETURN_NO_ERROR; }
XCamReturn X3aAnalyzer::init (uint32_t width, uint32_t height, double framerate) { XCamReturn ret = XCAM_RETURN_NO_ERROR; if (!_ae_handler.ptr() || !_awb_handler.ptr() || !_af_handler.ptr() || !_common_handler.ptr()) { XCAM_LOG_WARNING ( "analyzer:%s init failed, <prepare_handlers> need called first", XCAM_STR(get_name ())); return XCAM_RETURN_ERROR_PARAM; } XCAM_ASSERT (!_width && !_height); _width = width; _height = height; _framerate = framerate; ret = internal_init (width, height, _framerate); if (ret != XCAM_RETURN_NO_ERROR) { XCAM_LOG_WARNING ("analyzer init failed"); deinit (); return ret; } XCAM_LOG_INFO ( "Analyzer(%s) initialized(w:%d, h:%d).", XCAM_STR(get_name()), _width, _height); return XCAM_RETURN_NO_ERROR; }
XCamReturn CLKernel::load_from_source (const char *source, size_t length) { cl_kernel new_kernel_id = NULL; XCAM_ASSERT (source); if (!source) { XCAM_LOG_WARNING ("kernel:%s source empty", XCAM_STR (_name)); return XCAM_RETURN_ERROR_PARAM; } if (_kernel_id) { XCAM_LOG_WARNING ("kernel:%s already build yet", XCAM_STR (_name)); return XCAM_RETURN_ERROR_PARAM; } XCAM_ASSERT (_context.ptr ()); if (length == 0) length = strlen (source); new_kernel_id = _context->generate_kernel_id ( this, (const uint8_t *)source, length, CLContext::KERNEL_BUILD_SOURCE); XCAM_FAIL_RETURN( WARNING, new_kernel_id != NULL, XCAM_RETURN_ERROR_CL, "cl kernel(%s) load from source failed", XCAM_STR (_name)); _kernel_id = new_kernel_id; return XCAM_RETURN_NO_ERROR; }
SmartPtr<VKShader> VKDevice::create_shader (const char *file_name) { FileHandle file (file_name, "rb"); XCAM_FAIL_RETURN ( ERROR, file.is_valid (), NULL, "VKDevice load shader failed when opend shader file:%s.", XCAM_STR (file_name)); size_t file_size; XCAM_FAIL_RETURN ( ERROR, xcam_ret_is_ok (file.get_file_size (file_size)) || file_size == 0, NULL, "VKDevice load shader failed when read shader file:%s.", XCAM_STR (file_name)); std::vector<uint32_t> content (XCAM_ALIGN_UP (file_size, 4) / 4, 0); XCAM_FAIL_RETURN ( ERROR, xcam_ret_is_ok (file.read_file ((void *)content.data (), file_size)), NULL, "VKDevice load shader failed when read shader file:%s.", XCAM_STR (file_name)); file.close (); SmartPtr<VKShader> shader = create_shader (content); if (shader.ptr ()) shader->set_name (file_name); return shader; }
XCamReturn CLKernel::load_from_binary (const uint8_t *binary, size_t length) { cl_kernel new_kernel_id = NULL; XCAM_ASSERT (binary); if (!binary || !length) { XCAM_LOG_WARNING ("kernel:%s binary empty", XCAM_STR (_name)); return XCAM_RETURN_ERROR_PARAM; } if (_kernel_id) { XCAM_LOG_WARNING ("kernel:%s already build yet", XCAM_STR (_name)); return XCAM_RETURN_ERROR_PARAM; } XCAM_ASSERT (_context.ptr ()); new_kernel_id = _context->generate_kernel_id ( this, binary, length, CLContext::KERNEL_BUILD_BINARY); XCAM_FAIL_RETURN( WARNING, new_kernel_id != NULL, XCAM_RETURN_ERROR_CL, "cl kernel(%s) load from binary failed", XCAM_STR (_name)); _kernel_id = new_kernel_id; return XCAM_RETURN_NO_ERROR; }
bool CpfReader::read (ia_binary_data &binary) { if (!xcam_cpf_read (_name, _aiq_cpf, NULL)) { XCAM_LOG_ERROR ("parse CPF(%s) failed", XCAM_STR (_name)); return false; } binary.data = _aiq_cpf->data; binary.size = _aiq_cpf->size; XCAM_LOG_INFO ("read cpf(%s) ok", XCAM_STR (_name)); return true; }
XCamReturn CLKernel::execute ( const SmartPtr<CLKernel> self, bool block, CLEventList &events, SmartPtr<CLEvent> &event_out) { XCAM_ASSERT (self.ptr () == this); XCAM_ASSERT (_context.ptr ()); SmartPtr<CLEvent> kernel_event = event_out; if (!block && !kernel_event.ptr ()) { kernel_event = new CLEvent; } #if ENABLE_DEBUG_KERNEL XCAM_OBJ_PROFILING_START; #endif XCamReturn ret = _context->execute_kernel (self, NULL, events, kernel_event); XCAM_FAIL_RETURN ( ERROR, ret == XCAM_RETURN_NO_ERROR, ret, "kernel(%s) execute failed", XCAM_STR(_name)); if (block) { _context->finish (); } else { XCAM_ASSERT (kernel_event.ptr () && kernel_event->get_event_id ()); KernelUserData *user_data = new KernelUserData (self, kernel_event); user_data->arg_list.swap (_arg_list); ret = _context->set_event_callback (kernel_event, CL_COMPLETE, event_notify, user_data); if (ret != XCAM_RETURN_NO_ERROR) { XCAM_LOG_WARNING ("kernel(%s) set event callback failed", XCAM_STR (_name)); _context->finish (); delete user_data; } } _arg_list.clear (); #if ENABLE_DEBUG_KERNEL _context->finish (); char name[1024]; snprintf (name, 1024, "%s-%p", XCAM_STR (_name), this); XCAM_OBJ_PROFILING_END (name, XCAM_OBJ_DUR_FRAME_NUM); #endif return ret; }
XCamReturn V4l2Device::stop () { // stream off if (_active) { if (io_control (VIDIOC_STREAMOFF, &_capture_buf_type) < 0) { XCAM_LOG_WARNING ("device(%s) steamoff failed", XCAM_STR (_name)); } _active = false; } fini_buffer_pool (); XCAM_LOG_INFO ("device(%s) stopped", XCAM_STR (_name)); return XCAM_RETURN_NO_ERROR; }
XCamReturn PollThread::poll_subdev_event_loop () { XCamReturn ret = XCAM_RETURN_NO_ERROR; struct v4l2_event event; int poll_ret = 0; poll_ret = _event_dev->poll_event (PollThread::default_subdev_event_timeout); if (poll_ret < 0) { XCAM_LOG_WARNING ("poll event failed but continue"); ::usleep (100000); // 100ms return XCAM_RETURN_ERROR_TIMEOUT; } /* timeout */ if (poll_ret == 0) { XCAM_LOG_DEBUG ("poll event timeout and continue"); return XCAM_RETURN_ERROR_TIMEOUT; } xcam_mem_clear (event); ret = _event_dev->dequeue_event (event); if (ret != XCAM_RETURN_NO_ERROR) { XCAM_LOG_WARNING ("dequeue event failed on dev:%s", XCAM_STR(_event_dev->get_device_name())); return XCAM_RETURN_ERROR_IOCTL; } ret = handle_events (event); return ret; }
XCamReturn SmartAnalyzer::analyze (SmartPtr<BufferProxy> &buffer) { XCamReturn ret = XCAM_RETURN_NO_ERROR; X3aResultList results; if (!buffer.ptr ()) { XCAM_LOG_DEBUG ("SmartAnalyzer::analyze got NULL buffer!"); return XCAM_RETURN_ERROR_PARAM; } SmartHandlerList::iterator i_handler = _handlers.begin (); for (; i_handler != _handlers.end (); ++i_handler) { SmartPtr<SmartAnalysisHandler> handler = *i_handler; if (!handler->is_valid ()) continue; ret = handler->analyze (buffer, results); if (ret != XCAM_RETURN_NO_ERROR && ret != XCAM_RETURN_BYPASS) { XCAM_LOG_WARNING ("smart analyzer analyze handler(%s) context failed", XCAM_STR(handler->get_name())); handler->destroy_context (); } } if (!results.empty ()) { set_results_timestamp (results, buffer->get_timestamp ()); notify_calculation_done (results); } return XCAM_RETURN_NO_ERROR; }
XCamReturn V4l2Device::open () { struct v4l2_streamparm param; if (is_opened()) { XCAM_LOG_DEBUG ("device(%s) was already opened", XCAM_STR(_name)); return XCAM_RETURN_NO_ERROR; } if (!_name) { XCAM_LOG_DEBUG ("v4l2 device open failed, there's no device name"); return XCAM_RETURN_ERROR_PARAM; } _fd = ::open (_name, O_RDWR); if (_fd == -1) { XCAM_LOG_DEBUG ("open device(%s) failed", _name); return XCAM_RETURN_ERROR_IOCTL; } // set sensor id if (io_control (VIDIOC_S_INPUT, &_sensor_id) < 0) { XCAM_LOG_WARNING ("set sensor id(%d) failed but continue", _sensor_id); } // set capture mode xcam_mem_clear (param); param.type = _capture_buf_type; param.parm.capture.capturemode = _capture_mode; if (io_control (VIDIOC_S_PARM, ¶m) < 0) { XCAM_LOG_WARNING ("set capture mode(0x%08x) failed but continue", _capture_mode); } return XCAM_RETURN_NO_ERROR; }
XCamReturn X3aAnalyzer::stop () { _3a_analyzer_thread->triger_stop (); _3a_analyzer_thread->stop (); XCAM_LOG_INFO ("Analyzer(%s) stopped.", XCAM_STR(get_name())); return XCAM_RETURN_NO_ERROR; }
void AnalyzerCallback::x3a_calculation_failed (X3aAnalyzer *analyzer, int64_t timestamp, const char *msg) { XCAM_UNUSED (analyzer); XCAM_LOG_WARNING ( "Calculate 3a result failed, ts(" XCAM_TIMESTAMP_FORMAT "), msg:%s", XCAM_TIMESTAMP_ARGS (timestamp), XCAM_STR (msg)); }
bool V4l2Device::set_mem_type (enum v4l2_memory type) { if (is_activated ()) { XCAM_LOG_WARNING ("device(%s) set mem type failed", XCAM_STR (_name)); return false; } _memory_type = type; return true; }
XCamReturn CLImageHandler::create_buffer_pool (const VideoBufferInfo &video_info) { SmartPtr<DrmBoBufferPool> buffer_pool; SmartPtr<DrmDisplay> display; if (_buf_pool.ptr ()) return XCAM_RETURN_ERROR_PARAM; display = DrmDisplay::instance (); XCAM_FAIL_RETURN( WARNING, display.ptr (), XCAM_RETURN_ERROR_CL, "CLImageHandler(%s) failed to get drm dispay", XCAM_STR (_name)); if (_buf_pool_type == CLImageHandler::DrmBoPoolType) buffer_pool = new DrmBoBufferPool (display); else if (_buf_pool_type == CLImageHandler::CLBoPoolType) { SmartPtr<XCam::CLContext> context = CLDevice::instance()->get_context (); buffer_pool = new CLBoBufferPool (display, context); } XCAM_FAIL_RETURN( WARNING, buffer_pool.ptr (), XCAM_RETURN_ERROR_CL, "CLImageHandler(%s) create buffer pool failed, pool_type:%d", XCAM_STR (_name), (int32_t)_buf_pool_type); XCAM_ASSERT (buffer_pool.ptr ()); buffer_pool->set_swap_flags (_buf_swap_flags, _buf_swap_init_order); buffer_pool->set_video_info (video_info); XCAM_FAIL_RETURN( WARNING, buffer_pool->reserve (_buf_pool_size), XCAM_RETURN_ERROR_CL, "CLImageHandler(%s) failed to init drm buffer pool", XCAM_STR (_name)); _buf_pool = buffer_pool; return XCAM_RETURN_NO_ERROR; }
XCamReturn V4l2Device::start () { XCamReturn ret = XCAM_RETURN_NO_ERROR; // request buffer first ret = request_buffer (); XCAM_FAIL_RETURN ( ERROR, ret == XCAM_RETURN_NO_ERROR, ret, "device(%s) start failed", XCAM_STR (_name)); //alloc buffers ret = init_buffer_pool (); XCAM_FAIL_RETURN ( ERROR, ret == XCAM_RETURN_NO_ERROR, ret, "device(%s) start failed", XCAM_STR (_name)); //queue all buffers for (uint32_t i = 0; i < _buf_count; ++i) { SmartPtr<V4l2Buffer> &buf = _buf_pool [i]; XCAM_ASSERT (buf.ptr()); XCAM_ASSERT (buf->get_buf().index == i); ret = queue_buffer (buf); if (ret != XCAM_RETURN_NO_ERROR) { XCAM_LOG_ERROR ( "device(%s) start failed on queue index:%d", XCAM_STR (_name), i); stop (); return ret; } } // stream on if (io_control (VIDIOC_STREAMON, &_capture_buf_type) < 0) { XCAM_LOG_ERROR ( "device(%s) start failed on VIDIOC_STREAMON", XCAM_STR (_name)); stop (); return XCAM_RETURN_ERROR_IOCTL; } _active = true; XCAM_LOG_INFO ("device(%s) started successfully", XCAM_STR (_name)); return XCAM_RETURN_NO_ERROR; }
bool V4l2Device::set_buffer_count (uint32_t buf_count) { if (is_activated ()) { XCAM_LOG_WARNING ("device(%s) set buffer count failed", XCAM_STR (_name)); return false; } _buf_count = buf_count; return true; }
void X3aAnalyzer::notify_calculation_failed (AnalyzerHandler *handler, int64_t timestamp, const char *msg) { XCAM_UNUSED (handler); if (_callback) _callback->x3a_calculation_failed (this, timestamp, msg); XCAM_LOG_DEBUG ( "calculation failed on ts:" XCAM_TIMESTAMP_FORMAT ", reason:%s", XCAM_TIMESTAMP_ARGS (timestamp), XCAM_STR (msg)); }
XCamReturn X3aAnalyzer::start () { if (_3a_analyzer_thread->start () == false) { XCAM_LOG_WARNING ("analyzer thread start failed"); stop (); return XCAM_RETURN_ERROR_THREAD; } XCAM_LOG_INFO ("Analyzer(%s) started.", XCAM_STR(get_name())); return XCAM_RETURN_NO_ERROR; }
XCamReturn CLImageHandler::prepare_output_buf (SmartPtr<DrmBoBuffer> &input, SmartPtr<DrmBoBuffer> &output) { SmartPtr<BufferProxy> new_buf; XCamReturn ret = XCAM_RETURN_NO_ERROR; if (!_buf_pool.ptr ()) { VideoBufferInfo output_video_info; ret = prepare_buffer_pool_video_info (input->get_video_info (), output_video_info); XCAM_FAIL_RETURN( WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "CLImageHandler(%s) prepare output video info failed", XCAM_STR (_name)); ret = create_buffer_pool (output_video_info); XCAM_FAIL_RETURN( WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "CLImageHandler(%s) ensure drm buffer pool failed", XCAM_STR (_name)); } new_buf = _buf_pool->get_buffer (_buf_pool); XCAM_FAIL_RETURN( WARNING, new_buf.ptr(), XCAM_RETURN_ERROR_UNKNOWN, "CLImageHandler(%s) failed to get drm buffer from pool", XCAM_STR (_name)); new_buf->set_timestamp (input->get_timestamp ()); new_buf->copy_attaches (input); output = new_buf.dynamic_cast_ptr<DrmBoBuffer> (); XCAM_ASSERT (output.ptr ()); return XCAM_RETURN_NO_ERROR; }
XCamReturn V4l2SubDevice::dequeue_event (struct v4l2_event &event) { int ret = 0; XCAM_ASSERT (is_opened()); ret = this->io_control (VIDIOC_DQEVENT, &event); if (ret < 0) { XCAM_LOG_DEBUG ("subdev(%s) dequeue event failed", XCAM_STR(_name)); return XCAM_RETURN_ERROR_IOCTL; } return XCAM_RETURN_NO_ERROR; }
XCamReturn CLCloneImageHandler::prepare_output_buf (SmartPtr<DrmBoBuffer> &input, SmartPtr<DrmBoBuffer> &output) { XCAM_FAIL_RETURN ( ERROR, _clone_flags != (uint32_t)(SwappedBuffer::SwapNone), XCAM_RETURN_ERROR_PARAM, "CLCloneImageHandler(%s) clone output buffer failed since clone_flags none", XCAM_STR (get_name ())); XCAM_ASSERT (input.ptr ()); SmartPtr<SwappedBuffer> swap_input = input; SmartPtr<SwappedBuffer> swap_output = swap_input->swap_clone (swap_input, _clone_flags); SmartPtr<DrmBoBuffer> swapped_buf = swap_output.dynamic_cast_ptr<DrmBoBuffer> (); XCAM_FAIL_RETURN ( ERROR, swapped_buf.ptr (), XCAM_RETURN_ERROR_UNKNOWN, "CLCloneImageHandler(%s) clone output buffer failed(clone_flags:%d)", XCAM_STR (get_name ()), _clone_flags); output = swapped_buf; return XCAM_RETURN_NO_ERROR; }
void CLContext::context_pfn_notify ( const char* erro_info, const void *private_info, size_t cb, void *user_data ) { CLContext *context = (CLContext*) user_data; XCAM_UNUSED (context); XCAM_UNUSED (erro_info); XCAM_UNUSED (private_info); XCAM_UNUSED (cb); XCAM_LOG_DEBUG ("cl context pfn error:%s", XCAM_STR (erro_info)); }
bool AnalyzerThread::started () { XCamReturn ret = XCAM_RETURN_NO_ERROR; XCAM_ASSERT (_analyzer); ret = _analyzer->configure_3a (); if (ret != XCAM_RETURN_NO_ERROR) { _analyzer->notify_calculation_failed (NULL, 0, "configure 3a failed"); XCAM_LOG_WARNING ("analyzer(%s) configure 3a failed", XCAM_STR(_analyzer->get_name())); return false; } return true; }
XCamReturn CLKernel::clone (SmartPtr<CLKernel> kernel) { XCAM_FAIL_RETURN ( WARNING, kernel.ptr () && kernel->is_valid (), XCAM_RETURN_ERROR_CL, "cl kernel(%s) load from kernel failed", XCAM_STR (_name)); _kernel_id = kernel->get_kernel_id (); _parent_kernel = kernel; if (!_name && kernel->get_kernel_name ()) { _name = strndup (kernel->get_kernel_name (), XCAM_MAX_STR_SIZE); } return XCAM_RETURN_NO_ERROR; }
XCamReturn X3aAnalyzer::deinit () { internal_deinit(); _ae_handler.release (); _awb_handler.release (); _af_handler.release (); _common_handler.release (); _width = 0; _height = 0; XCAM_LOG_INFO ("Analyzer(%s) deinited.", XCAM_STR(get_name())); return XCAM_RETURN_NO_ERROR; }
XCamReturn V4l2Device::queue_buffer (SmartPtr<V4l2Buffer> &buf) { XCAM_ASSERT (buf.ptr()); buf->reset (); struct v4l2_buffer v4l2_buf = buf->get_buf (); XCAM_ASSERT (v4l2_buf.index < _buf_count); XCAM_LOG_DEBUG ("device(%s) queue buffer index:%d", XCAM_STR (_name), v4l2_buf.index); if (io_control (VIDIOC_QBUF, &v4l2_buf) < 0) { XCAM_LOG_ERROR("fail to enqueue buffer index:%d.", v4l2_buf.index); return XCAM_RETURN_ERROR_IOCTL; } return XCAM_RETURN_NO_ERROR; }
XCamReturn SmartAnalyzer::internal_init (uint32_t width, uint32_t height, double framerate) { XCAM_UNUSED (width); XCAM_UNUSED (height); XCAM_UNUSED (framerate); SmartHandlerList::iterator i_handler = _handlers.begin (); for (; i_handler != _handlers.end (); ++i_handler) { SmartPtr<SmartAnalysisHandler> handler = *i_handler; XCamReturn ret = handler->create_context (handler); if (ret != XCAM_RETURN_NO_ERROR) { XCAM_LOG_WARNING ("smart analyzer initilize handler(%s) context failed", XCAM_STR(handler->get_name())); } } return XCAM_RETURN_NO_ERROR; }