|
|
@ -306,14 +306,13 @@ void SpectraCamera::camera_open(VisionIpcServer *v, cl_device_id device_id, cl_c |
|
|
|
LOGD("camera init %d", cc.camera_num); |
|
|
|
LOGD("camera init %d", cc.camera_num); |
|
|
|
buf.init(device_id, ctx, this, v, ife_buf_depth, cc.stream_type); |
|
|
|
buf.init(device_id, ctx, this, v, ife_buf_depth, cc.stream_type); |
|
|
|
camera_map_bufs(); |
|
|
|
camera_map_bufs(); |
|
|
|
enqueue_req_multi(1, ife_buf_depth, 0); |
|
|
|
enqueue_req_multi(1, ife_buf_depth); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SpectraCamera::enqueue_req_multi(uint64_t start, int n, bool dp) { |
|
|
|
void SpectraCamera::enqueue_req_multi(uint64_t start, int n) { |
|
|
|
for (uint64_t i = start; i < start + n; ++i) { |
|
|
|
for (uint64_t request_id = start; request_id < start + n; ++request_id) { |
|
|
|
uint64_t idx = (i - 1) % ife_buf_depth; |
|
|
|
uint64_t idx = (request_id - 1) % ife_buf_depth; |
|
|
|
request_ids[idx] = i; |
|
|
|
enqueue_buffer(idx, request_id); |
|
|
|
enqueue_buffer(idx, dp); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -904,9 +903,10 @@ void SpectraCamera::config_ife(int idx, int request_id, bool init) { |
|
|
|
assert(ret == 0); |
|
|
|
assert(ret == 0); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SpectraCamera::enqueue_buffer(int i, bool dp) { |
|
|
|
// Enqueue buffer for the given index and return true if the frame is ready
|
|
|
|
|
|
|
|
bool SpectraCamera::enqueue_buffer(int i, uint64_t request_id) { |
|
|
|
int ret; |
|
|
|
int ret; |
|
|
|
uint64_t request_id = request_ids[i]; |
|
|
|
bool frame_ready = false; |
|
|
|
|
|
|
|
|
|
|
|
// Before queuing up a new frame, wait for the
|
|
|
|
// Before queuing up a new frame, wait for the
|
|
|
|
// previous one in this slot (index) to come in.
|
|
|
|
// previous one in this slot (index) to come in.
|
|
|
@ -935,13 +935,9 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// in IFE_PROCESSED mode, we can't know the true EOF, so recover it with sensor readout time
|
|
|
|
|
|
|
|
buf.frame_metadata[i].timestamp_eof = buf.frame_metadata[i].timestamp_sof + sensor->readout_time_ns; |
|
|
|
|
|
|
|
buf.frame_metadata[i].timestamp_end_of_isp = (uint64_t)nanos_since_boot(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// all good, hand off frame
|
|
|
|
// all good, hand off frame
|
|
|
|
if (dp && ret == 0) { |
|
|
|
if (ret == 0) { |
|
|
|
buf.queue(i); |
|
|
|
frame_ready = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ret != 0) { |
|
|
|
if (ret != 0) { |
|
|
@ -984,6 +980,8 @@ void SpectraCamera::enqueue_buffer(int i, bool dp) { |
|
|
|
// submit request to IFE and BPS
|
|
|
|
// submit request to IFE and BPS
|
|
|
|
config_ife(i, request_id); |
|
|
|
config_ife(i, request_id); |
|
|
|
if (output_type == ISP_BPS_PROCESSED) config_bps(i, request_id); |
|
|
|
if (output_type == ISP_BPS_PROCESSED) config_bps(i, request_id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return frame_ready; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SpectraCamera::destroySyncObjectAt(int index) { |
|
|
|
void SpectraCamera::destroySyncObjectAt(int index) { |
|
|
@ -1368,8 +1366,9 @@ void SpectraCamera::camera_close() { |
|
|
|
LOGD("destroyed session %d: %d", cc.camera_num, ret); |
|
|
|
LOGD("destroyed session %d: %d", cc.camera_num, ret); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { |
|
|
|
// Processes camera events and returns true if the frame is ready for further processing
|
|
|
|
if (!enabled) return; |
|
|
|
bool SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { |
|
|
|
|
|
|
|
if (!enabled) return false; |
|
|
|
|
|
|
|
|
|
|
|
// ID from the qcom camera request manager
|
|
|
|
// ID from the qcom camera request manager
|
|
|
|
uint64_t request_id = event_data->u.frame_msg.request_id; |
|
|
|
uint64_t request_id = event_data->u.frame_msg.request_id; |
|
|
@ -1378,13 +1377,11 @@ void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { |
|
|
|
uint64_t frame_id_raw = event_data->u.frame_msg.frame_id; |
|
|
|
uint64_t frame_id_raw = event_data->u.frame_msg.frame_id; |
|
|
|
|
|
|
|
|
|
|
|
if (request_id != 0) { // next ready
|
|
|
|
if (request_id != 0) { // next ready
|
|
|
|
int buf_idx = (request_id - 1) % ife_buf_depth; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check for skipped_last frames
|
|
|
|
// check for skipped_last frames
|
|
|
|
if (frame_id_raw > frame_id_raw_last + 1 && !skipped_last) { |
|
|
|
if (frame_id_raw > frame_id_raw_last + 1 && !skipped_last) { |
|
|
|
LOGE("camera %d realign", cc.camera_num); |
|
|
|
LOGE("camera %d realign", cc.camera_num); |
|
|
|
clear_req_queue(); |
|
|
|
clear_req_queue(); |
|
|
|
enqueue_req_multi(request_id + 1, ife_buf_depth - 1, 0); |
|
|
|
enqueue_req_multi(request_id + 1, ife_buf_depth - 1); |
|
|
|
skipped_last = true; |
|
|
|
skipped_last = true; |
|
|
|
} else if (frame_id_raw == frame_id_raw_last + 1) { |
|
|
|
} else if (frame_id_raw == frame_id_raw_last + 1) { |
|
|
|
skipped_last = false; |
|
|
|
skipped_last = false; |
|
|
@ -1393,37 +1390,47 @@ void SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { |
|
|
|
// check for dropped requests
|
|
|
|
// check for dropped requests
|
|
|
|
if (request_id > request_id_last + 1) { |
|
|
|
if (request_id > request_id_last + 1) { |
|
|
|
LOGE("camera %d dropped requests %ld %ld", cc.camera_num, request_id, request_id_last); |
|
|
|
LOGE("camera %d dropped requests %ld %ld", cc.camera_num, request_id, request_id_last); |
|
|
|
enqueue_req_multi(request_id_last + 1 + ife_buf_depth, request_id - (request_id_last + 1), 0); |
|
|
|
enqueue_req_multi(request_id_last + 1 + ife_buf_depth, request_id - (request_id_last + 1)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// metas
|
|
|
|
// metas
|
|
|
|
frame_id_raw_last = frame_id_raw; |
|
|
|
frame_id_raw_last = frame_id_raw; |
|
|
|
request_id_last = request_id; |
|
|
|
request_id_last = request_id; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int buf_idx = (request_id - 1) % ife_buf_depth; |
|
|
|
uint64_t timestamp = event_data->u.frame_msg.timestamp; // this is timestamped in the kernel's SOF IRQ callback
|
|
|
|
uint64_t timestamp = event_data->u.frame_msg.timestamp; // this is timestamped in the kernel's SOF IRQ callback
|
|
|
|
if (syncFirstFrame(cc.camera_num, request_id, frame_id_raw, timestamp)) { |
|
|
|
if (syncFirstFrame(cc.camera_num, request_id, frame_id_raw, timestamp)) { |
|
|
|
auto &meta_data = buf.frame_metadata[buf_idx]; |
|
|
|
|
|
|
|
meta_data.frame_id = frame_id_raw - camera_sync_data[cc.camera_num].frame_id_offset; |
|
|
|
|
|
|
|
meta_data.request_id = request_id; |
|
|
|
|
|
|
|
meta_data.timestamp_sof = timestamp; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// wait for this frame's EOF, then queue up the next one
|
|
|
|
// wait for this frame's EOF, then queue up the next one
|
|
|
|
enqueue_req_multi(request_id + ife_buf_depth, 1, true); |
|
|
|
if (enqueue_buffer(buf_idx, request_id + ife_buf_depth)) { |
|
|
|
//LOGW("camerad %d synced req %d fid %d, publishing ts %.2f cereal_frame_id %d", cc.camera_num, (int)request_id, (int)frame_id_raw, (double)(timestamp)*1e-6, meta_data.frame_id);
|
|
|
|
// Frame is ready
|
|
|
|
|
|
|
|
buf.cur_buf_idx = buf_idx; |
|
|
|
|
|
|
|
buf.cur_frame_data = { |
|
|
|
|
|
|
|
.frame_id = (uint32_t)(frame_id_raw - camera_sync_data[cc.camera_num].frame_id_offset), |
|
|
|
|
|
|
|
.request_id = (uint32_t)request_id, |
|
|
|
|
|
|
|
.timestamp_sof = timestamp, |
|
|
|
|
|
|
|
// in IFE_PROCESSED mode, we can't know the true EOF, so recover it with sensor readout time
|
|
|
|
|
|
|
|
.timestamp_eof = timestamp + sensor->readout_time_ns, |
|
|
|
|
|
|
|
.timestamp_end_of_isp = (uint64_t)nanos_since_boot(), |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// LOGW("camerad %d synced req %d fid %d, publishing ts %.2f cereal_frame_id %d", cc.camera_num, (int)request_id, (int)frame_id_raw, (double)(timestamp)*1e-6, meta_data.frame_id);
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Frames not yet synced
|
|
|
|
// Frames not yet synced
|
|
|
|
enqueue_req_multi(request_id + ife_buf_depth, 1, false); |
|
|
|
enqueue_req_multi(request_id + ife_buf_depth, 1); |
|
|
|
//LOGW("camerad %d not synced req %d fid %d", cc.camera_num, (int)request_id, (int)frame_id_raw);
|
|
|
|
// LOGW("camerad %d not synced req %d fid %d", cc.camera_num, (int)request_id, (int)frame_id_raw);
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { // not ready
|
|
|
|
} else { // not ready
|
|
|
|
if (frame_id_raw > frame_id_raw_last + 10) { |
|
|
|
if (frame_id_raw > frame_id_raw_last + 10) { |
|
|
|
LOGE("camera %d reset after half second of no response", cc.camera_num); |
|
|
|
LOGE("camera %d reset after half second of no response", cc.camera_num); |
|
|
|
clear_req_queue(); |
|
|
|
clear_req_queue(); |
|
|
|
enqueue_req_multi(request_id_last + 1, ife_buf_depth, 0); |
|
|
|
enqueue_req_multi(request_id_last + 1, ife_buf_depth); |
|
|
|
frame_id_raw_last = frame_id_raw; |
|
|
|
frame_id_raw_last = frame_id_raw; |
|
|
|
skipped_last = true; |
|
|
|
skipped_last = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool SpectraCamera::syncFirstFrame(int camera_id, uint64_t request_id, uint64_t raw_id, uint64_t timestamp) { |
|
|
|
bool SpectraCamera::syncFirstFrame(int camera_id, uint64_t request_id, uint64_t raw_id, uint64_t timestamp) { |
|
|
|