Linux_SDK_V1.0.2

This commit is contained in:
thead_admin
2022-11-22 15:44:55 +08:00
parent b68c608415
commit c9c8f34f4e
11 changed files with 2122 additions and 95 deletions

View File

@@ -105,3 +105,14 @@ $(OBJS_8): %.o:%.c
@echo ">>> Compiling" $< "..."
$(CC) $(CFLAGS) $(INCLUDE) -c -o .obj/$(notdir $@) $<
OBJS_9 = $(SRCS_9:.c=.o)
$(TARGET_9): $(OBJS_9) $(PREPARE)
@mkdir -p $(OUTPUT_DIR)
@echo ">>> Linking" $@ "..."
$(CC) $(LFLAGS) -o $@ $(addprefix .obj/,$(notdir $(OBJS_9))) -Wl,--start-group $(LIBS) $(LIBS_8) -Wl,--end-group
cp $@ $(OUTPUT_DIR)
$(OBJS_9): %.o:%.c
@mkdir -p .obj
@echo ">>> Compiling" $< "..."
$(CC) $(CFLAGS) $(INCLUDE) -c -o .obj/$(notdir $@) $<

View File

@@ -17,8 +17,9 @@ PREPARE := lib_camera
ifeq ($(PLATFORM),light)
CFLAGS += -I$(VISYS_SYM_PATH)/usr/include/plink/
CFLAGS += -I$(VISYS_SYM_PATH)/usr/include/vidmem/
CFLAGS += -I$(VISYS_SYM_PATH)/usr/include/dsp/lib/inc/
LIBS += -lstdc++ -lpthread
LIBS += -lvmem -lplink
LIBS += -lvmem -lplink -ldsp
endif
@@ -53,10 +54,13 @@ SRCS_7 = cam_demo_ir.c camera_frame_display.c
TARGET_8 := cam_demo_multi
SRCS_8 = cam_demo_multi.c camera_frame_display.c
TARGET_9 := cam_demo_dual_ir
SRCS_9 = cam_demo_dual_ir.c
ifeq ($(PLATFORM),simulator)
TARGET_ALL := $(TARGET_1) $(TARGET_2) $(TARGET_3) $(TARGET_4)
else
TARGET_ALL := $(TARGET_1) $(TARGET_2) $(TARGET_3) $(TARGET_5) $(TARGET_6) $(TARGET_7) $(TARGET_8)
TARGET_ALL := $(TARGET_1) $(TARGET_2) $(TARGET_3) $(TARGET_5) $(TARGET_6) $(TARGET_7) $(TARGET_8) $(TARGET_9)
endif
all: $(TARGET_ALL)
@@ -78,6 +82,10 @@ clean:
rm -f $(TARGET_3) $(OUTPUT_DIR)/camera_demo3.conf
rm -f $(TARGET_4) $(OUTPUT_DIR)/$(TARGET_4)
rm -f $(TARGET_5) $(OUTPUT_DIR)/$(TARGET_5)
rm -f $(TARGET_6) $(OUTPUT_DIR)/$(TARGET_6)
rm -f $(TARGET_7) $(OUTPUT_DIR)/$(TARGET_7)
rm -f $(TARGET_8) $(OUTPUT_DIR)/$(TARGET_8)
rm -f $(TARGET_9) $(OUTPUT_DIR)/$(TARGET_9)
make -C ./opencv clean
include $(DIR_TO_ROOT)/common_target.mk

File diff suppressed because it is too large Load Diff

View File

@@ -58,6 +58,7 @@ static event_queue_item_t *dequeue_event(channel_handle_ctx_t *ctx)
if(!ev)
{
pthread_mutex_unlock(&ctx->event_queue.mutex);
usleep(1000);
return NULL;
}
@@ -223,7 +224,8 @@ int main(int argc, char *argv[])
int frame_num = 0;
algo_2 = "dsp1_dummy_algo_flo";
algo_1 = "dsp1_dummy_algo_flo_1";
switch(argc)
int ret = 0;
switch(argc)
{
case 0:
case 1:
@@ -303,8 +305,12 @@ int main(int argc, char *argv[])
/* The caps are: Video capture, metadata capture */
// 打开Camera设备获取句柄作为后续操对象
csi_cam_handle_t cam_handle;
csi_camera_open(&cam_handle, camera_info.device_name);
LOG_O("csi_camera_open() OK\n");
ret = csi_camera_open(&cam_handle, camera_info.device_name);
if (ret) {
LOG_E("Failed to csi_camera_open %s\n", camera_info.device_name);
exit(-1);
}
LOG_O("csi_camera_open() OK\n");
// 获取Camera支持的工作模式
struct csi_camera_modes camera_modes;
@@ -332,7 +338,10 @@ int main(int argc, char *argv[])
chn_cfg.meta_fields = CSI_CAMERA_META_DEFAULT_FIELDS;
chn_cfg.capture_type = CSI_CAMERA_CHANNEL_CAPTURE_VIDEO |
CSI_CAMERA_CHANNEL_CAPTURE_META;
csi_camera_channel_open(cam_handle, &chn_cfg);
ret = csi_camera_channel_open(cam_handle, &chn_cfg);
if (ret) {
exit(-1);
}
LOG_O("CSI_CAMERA_CHANNEL_0: csi_camera_channel_open() OK\n");
@@ -346,7 +355,10 @@ int main(int argc, char *argv[])
chn_cfg.meta_fields = CSI_CAMERA_META_DEFAULT_FIELDS;
chn_cfg.capture_type = CSI_CAMERA_CHANNEL_CAPTURE_VIDEO |
CSI_CAMERA_CHANNEL_CAPTURE_META;
csi_camera_channel_open(cam_handle, &chn_cfg);
ret = csi_camera_channel_open(cam_handle, &chn_cfg);
if (ret) {
exit(-1);
}
LOG_O("CSI_CAMERA_CHANNEL_1: csi_camera_channel_open() OK\n");
// 订阅Event
@@ -402,8 +414,7 @@ int main(int argc, char *argv[])
if(csi_camera_set_dsp_algo_param(cam_handle, cb_context[0].dsp_id,cb_context[0].dsp_path, &algo_param_1))
{
LOG_E("set DSP algo fail\n");
LOG_E("set DSP algo fail\n");
}
@@ -436,11 +447,18 @@ int main(int argc, char *argv[])
csi_camera_projection_led_set_mode(cam_handle, LED_IR_ENABLE);
csi_camera_floodlight_led_set_mode(cam_handle, LED_IR_ENABLE);
csi_camera_led_enable(cam_handle, LED_FLOODLIGHT_PROJECTION);
csi_camera_led_set_switch_mode(cam_handle, SWITCH_MODE_PROJECTION_EVEN_FLOODLIGHT_ODD);
// 开始从channel中取出准备好的frame
csi_camera_channel_start(cam_handle, CSI_CAMERA_CHANNEL_0);
csi_camera_channel_start(cam_handle, CSI_CAMERA_CHANNEL_1);
LOG_O("Channel start OK\n");
ret = csi_camera_channel_start(cam_handle, CSI_CAMERA_CHANNEL_0);
if (ret) {
exit(-1);
}
ret = csi_camera_channel_start(cam_handle, CSI_CAMERA_CHANNEL_1);
if (ret) {
exit(-1);
}
LOG_O("Channel start OK\n");
// 处理订阅的Event
csi_frame_s frame;
@@ -450,14 +468,21 @@ int main(int argc, char *argv[])
while (running) {
int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
event_item = malloc(sizeof( event_queue_item_t));
csi_camera_get_event(event_handle, &event_item->evet, timeout);
LOG_O("event.type = %d, event.id = %d\n",event_item->evet.type, event_item->evet.id);
if(csi_camera_get_event(event_handle, &event_item->evet, timeout))
{
LOG_E("get event timeout\n");
free(event_item);
continue;
}
LOG_O("event.type = %d, event.id = %d\n",event_item->evet.type, event_item->evet.id);
switch (event_item->evet.type) {
case CSI_CAMERA_EVENT_TYPE_CAMERA:
switch (event_item->evet.id) {
case CSI_CAMERA_EVENT_ERROR:
// do sth.
LOG_E("CSI_CAMERA_EVENT_ERROR reprot\n");
break;
case CSI_CAMERA_EVENT_WARNING:
LOG_W("CSI_CAMERA_EVENT_ERROR reprot\n");
break;
default:
break;
@@ -521,6 +546,7 @@ int main(int argc, char *argv[])
csi_camera_destory_event(event_handle);
csi_camera_channel_close(cam_handle, CSI_CAMERA_CHANNEL_0);
csi_camera_channel_close(cam_handle, CSI_CAMERA_CHANNEL_1);
csi_camera_close(cam_handle);
}

View File

@@ -229,7 +229,11 @@ int main(int argc, char *argv[])
get_system_time(__func__, __LINE__);
// 打开Camera设备获取句柄作为后续操对象
csi_cam_handle_t cam_handle;
csi_camera_open(&cam_handle, camera_info.device_name);
ret = csi_camera_open(&cam_handle, camera_info.device_name);
if (ret) {
LOG_E("Failed to csi_camera_open %s\n", camera_info.device_name);
exit(-1);
}
get_system_time(__func__, __LINE__);
// 获取Camera支持的工作模式
struct csi_camera_modes camera_modes;
@@ -317,9 +321,10 @@ int main(int argc, char *argv[])
if (csi_camera_set_property(cam_handle, &properties) < 0) {
LOG_O("set_property fail!\n");
}
LOG_O("set_property ok!\n");
else
{
LOG_O("set_property ok!\n");
}
// extern int csi_camera_set_pp_path_param(csi_cam_handle_t cam_handle, uint16_t line_num,uint16_t buf_mode);
// csi_camera_set_pp_path_param(cam_handle,80,0);
@@ -440,8 +445,12 @@ int main(int argc, char *argv[])
}
*/
// 开始从channel中取出准备好的frame
csi_camera_channel_start(cam_handle, chn_id);
get_system_time(__func__, __LINE__);
ret = csi_camera_channel_start(cam_handle, chn_id);
if (ret) {
LOG_E("Failed to csi_camera_channel_start ch%d\n", chn_id);
exit(-1);
}
get_system_time(__func__, __LINE__);
// 处理订阅的Event
csi_frame_s frame;
struct csi_camera_event event;
@@ -453,7 +462,11 @@ int main(int argc, char *argv[])
}
}
int timeout = -1; // unit: ms, -1 means wait forever, or until error occurs
csi_camera_get_event(event_handle, &event, timeout);
if(csi_camera_get_event(event_handle, &event, timeout))
{
LOG_E("Failed to get event \n");
continue;
}
// printf("%s event.type = %d, event.id = %d\n", __func__, event.type, event.id);
switch (event.type) {
case CSI_CAMERA_EVENT_TYPE_CAMERA:
@@ -493,7 +506,11 @@ int main(int argc, char *argv[])
LOG_O("%s %d read_frame_count = %d, frame_count = %ld, fps = %.2f diff = %ld\n", __func__, __LINE__, read_frame_count, demo_fps.frameNumber, demo_fps.fps, diff);
for (int i = 0; i < read_frame_count; i++) {
csi_camera_get_frame(cam_handle, chn_id, &frame, timeout);
if(csi_camera_get_frame(cam_handle, chn_id, &frame, timeout))
{
LOG_W("get frame fail\n");
continue;
}
#ifdef PLATFORM_SIMULATOR
if (frame.img.type == CSI_IMG_TYPE_DMA_BUF) {
void *phyaddr = vi_mem_import(frame.img.dmabuf[0].fds);
@@ -504,7 +521,6 @@ int main(int argc, char *argv[])
show_frame_image(frame.img.usr_addr[0], frame.img.height, frame.img.width);
}
#endif
// printf("main 443 phyaddr=%p\n", vi_mem_import(frame.img.dmabuf[0].fds));
dump_camera_meta(&frame);
chn_cfg.chn_id = chn_id;
csi_camera_channel_query(cam_handle, &chn_cfg);
@@ -515,10 +531,9 @@ int main(int argc, char *argv[])
}
if (display_enable == 1) {
display_camera_frame(display_plink, &frame);
continue;
}
// csi_camera_frame_unlock(cam_handle, &frame);
csi_camera_put_frame(&frame);
csi_frame_release(&frame);
}
break;

View File

@@ -265,11 +265,6 @@ int main(int argc, char *argv[])
CSI_CAMERA_CHANNEL_0);
csi_camera_get_frame(cam_handle,CSI_CAMERA_CHANNEL_0, &frame, timeout);
// frame.image: {.width, .height, .pix_fmt, .dma-buf}
//show_frame_image(frame.image); // 伪代码
// frame.meta: {.count,
// .meta_data[]={meta_id, type,
// union{int_value, str_value, ...}}}
#ifdef PLATFORM_SIMULATOR
camera_action_image_display(&frame);

View File

@@ -103,7 +103,7 @@ again:
/* Show operation result */
cam_id = item_activate_selected_pos();
//char str_buf[256];
bool opened = (camera_open(cam_session, cam_id) == 0);
bool opened = (camera_open(cam_session, "/dev/video0") == 0);
snprintf(str_buf, sizeof(str_buf),
"Open the below camera %s:\n"
"\t id=%d \n\t name='%s' \n\t device='%s' \n\t bus='%s'\n",

View File

@@ -38,11 +38,14 @@ typedef struct _CsiPlinkContext
int useplink;
int exitplink;
CsiPictureBuffer sendbuffer[NUM_OF_BUFFERS];
csi_frame_s frame_buf[NUM_OF_BUFFERS];
int sendid;
int available_bufs;
void *vmem;
PlinkHandle plink;
PlinkChannelID chnid;
pthread_t buf_release_thread;
pthread_mutex_t mutex;
} CsiPlinkContext;
static int get_buffer_count(PlinkPacket *pkt)
{
@@ -65,7 +68,64 @@ static int get_buffer_count(PlinkPacket *pkt)
return ret;
}
static void allocate_sendbuffers(CsiPictureBuffer picbuffers[NUM_OF_BUFFERS], unsigned int size, void *vmem)
static void* camera_buf_release_process(CsiPlinkContext * plink_ctx)
{
PlinkPacket pkt = {0};
if(plink_ctx == NULL)
{
return NULL;
}
LOG_O("Process is runing.....\n");
while(!plink_ctx->exitplink)
{
if (plink_ctx->plink != NULL) {
if (PLINK_wait(plink_ctx->plink, plink_ctx->chnid, 1000) == PLINK_STATUS_OK)
{
if (PLINK_recv(plink_ctx->plink, plink_ctx->chnid, &pkt) != PLINK_STATUS_OK) {
plink_ctx->exitplink = 1;
break;
}
int count = get_buffer_count(&pkt);
if (count >= 0)
{
PlinkMsg *hdr;
int resp_id;
for(int i=0;i<count;i++)
{
hdr = (PlinkMsg *)(pkt.list[i]);
resp_id = hdr->msg;
if((resp_id>=NUM_OF_BUFFERS))
{
LOG_W("invalid resp_id:%d\n",resp_id);
continue;
}
if(plink_ctx->frame_buf[resp_id].img.dmabuf[0].fds!= 0)
{
csi_camera_put_frame(&plink_ctx->frame_buf[resp_id]);
LOG_D("release resp_id:%d, fd:%d\n",resp_id,plink_ctx->frame_buf[resp_id].img.dmabuf[0].fds);
plink_ctx->frame_buf[resp_id].img.dmabuf[0].fds = 0;
}
}
pthread_mutex_lock(&plink_ctx->mutex);
plink_ctx->available_bufs += count;
pthread_mutex_unlock(&plink_ctx->mutex);
}
else {
fprintf(stderr, "[SERVER] Exit!\n");
plink_ctx->exitplink = 1;
break;
}
}else
{
LOG_W("Plink Resp timeout\n");
}
}
}
LOG_O("Process is exit .....\n");
return NULL;
}
static int allocate_sendbuffers(CsiPictureBuffer picbuffers[NUM_OF_BUFFERS], unsigned int size, void *vmem)
{
unsigned int buffer_size = (size + 0xFFF) & ~0xFFF;
VmemParams params;
@@ -73,7 +133,9 @@ static void allocate_sendbuffers(CsiPictureBuffer picbuffers[NUM_OF_BUFFERS], un
params.flags = VMEM_FLAG_CONTIGUOUS | VMEM_FLAG_4GB_ADDR;
for (int i = 0; i < NUM_OF_BUFFERS; i++)
{
VMEM_allocate(vmem, &params);
if (VMEM_allocate(vmem, &params) != 0) {
return -1;
}
VMEM_mmap(vmem, &params);
VMEM_export(vmem, &params);
LOG_O("[SERVER] mmap %p from %x with size %d, dma-buf fd %d\n",
@@ -146,7 +208,9 @@ void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg)
case CSI_PIX_FMT_BGR:
{
framesize = stride * 304 * 3; //stride * chn_cfg->img_fmt.height * 3;
allocate_sendbuffers(plink_ctx->sendbuffer, framesize, plink_ctx->vmem);
if (allocate_sendbuffers(plink_ctx->sendbuffer, framesize, plink_ctx->vmem) != 0) {
return NULL;
}
// reset to black picture
uint32_t lumasize = stride * chn_cfg->img_fmt.height;
for (int i = 0; i < NUM_OF_BUFFERS; i++)
@@ -158,7 +222,9 @@ void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg)
default:
{
framesize = stride * chn_cfg->img_fmt.height * 3 / 2;
allocate_sendbuffers(plink_ctx->sendbuffer, framesize, plink_ctx->vmem);
if (allocate_sendbuffers(plink_ctx->sendbuffer, framesize, plink_ctx->vmem) != 0) {
return NULL;
}
// reset to black picture
uint32_t lumasize = stride * chn_cfg->img_fmt.height;
for (int i = 0; i < NUM_OF_BUFFERS; i++) {
@@ -178,6 +244,10 @@ void *vi_plink_create(csi_camera_channel_cfg_s *chn_cfg)
plink_ctx->sendid = 0;
plink_ctx->available_bufs = NUM_OF_BUFFERS;
memset(plink_ctx->frame_buf,0x0,sizeof(plink_ctx->frame_buf));
pthread_mutex_init(&plink_ctx->mutex,NULL);
pthread_create(&plink_ctx->buf_release_thread,NULL,(void *)camera_buf_release_process,plink_ctx);
return plink_ctx;
}
@@ -187,6 +257,9 @@ void vi_plink_release(void * plink)
CsiPlinkContext * plink_ctx = (CsiPlinkContext *)plink;
if(plink_ctx)
{
plink_ctx->exitplink=1;
pthread_join(plink_ctx->buf_release_thread,NULL);
PLINK_close(plink_ctx->plink,plink_ctx->chnid);
VMEM_destroy(plink_ctx->vmem);
}
@@ -203,40 +276,12 @@ void display_camera_frame(void *plink, csi_frame_s *frame)
}
LOG_O("%sfmt=%d img.strides[0] = %d\n", __func__,frame->img.pix_format, frame->img.strides[0]);
LOG_O("fmt=%d img.strides[0] = %d\n",frame->img.pix_format, frame->img.strides[0]);
if (!plink_ctx->exitplink) {
struct timeval tv_start, tv_end, tv_duration;
gettimeofday(&tv_start, 0);
// retrieve buffers
PlinkPacket pkt = {0};
if (plink_ctx->plink != NULL) {
while (PLINK_wait(plink_ctx->plink, plink_ctx->chnid, 0) == PLINK_STATUS_OK)
{
if (PLINK_recv(plink_ctx->plink, plink_ctx->chnid, &pkt) != PLINK_STATUS_OK) {
plink_ctx->exitplink = 1;
break;
}
int count = get_buffer_count(&pkt);
if (count >= 0)
plink_ctx->available_bufs += count;
else {
fprintf(stderr, "[SERVER] Exit!\n");
plink_ctx->exitplink = 1;
break;
}
}
}
/*
void *phy_address = NULL;
int dmabuf_fd = -1;
if (vi_mem_dmabuf_isenable()) {
phy_address = vi_mem_unmap(frame->img.usr_addr[0]);
dmabuf_fd = vi_mem_export(phy_address);
}
*/
// send one buffer if there is available slot
if (frame->img.type == CSI_IMG_TYPE_DMA_BUF && !plink_ctx->exitplink
&& plink_ctx->available_bufs > 0 && plink_ctx->plink != NULL && ((frame->img.pix_format == CSI_PIX_FMT_RAW_8BIT)|| (frame->img.pix_format == CSI_PIX_FMT_RAW_12BIT))) {
@@ -245,15 +290,12 @@ void display_camera_frame(void *plink, csi_frame_s *frame)
uint32_t dstw = frame->img.width;//800;
uint32_t dsth = frame->img.height;//1280;
uint32_t dsts = frame->img.strides[0];//896;
i++;
sprintf(str, "echo frame is %d > ~/frame", i);
system(str);
PlinkRawInfo info = {0};
info.header.type = PLINK_TYPE_2D_RAW;
info.header.size = DATA_SIZE(info);
info.header.id = plink_ctx->sendid + 1;
info.header.id = plink_ctx->sendid;
info.format = PLINK_COLOR_FormatRawBayer10bit;
// info.bus_address = vi_mem_import(frame->img.dmabuf[0].fds) + frame->img.dmabuf[0].offset;
@@ -266,12 +308,20 @@ void display_camera_frame(void *plink, csi_frame_s *frame)
pkt.list[0] = &info;
pkt.num = 1;
pkt.fd = frame->img.dmabuf[0].fds;
if(plink_ctx->frame_buf[plink_ctx->sendid].img.dmabuf[0].fds!=0)
{
LOG_W("previous sendid :%d,fd %d not release,release it now\n",plink_ctx->sendid,plink_ctx->frame_buf[plink_ctx->sendid].img.dmabuf[0].fds);
csi_camera_put_frame(&plink_ctx->frame_buf[plink_ctx->sendid]);
}
memcpy(&plink_ctx->frame_buf[plink_ctx->sendid],frame,sizeof(csi_frame_s));
plink_ctx->sendid = (plink_ctx->sendid + 1) % NUM_OF_BUFFERS;
if (PLINK_send(plink_ctx->plink, plink_ctx->chnid, &pkt) != PLINK_STATUS_OK)
plink_ctx->exitplink = 1;
gettimeofday(&tv_end, 0);
timersub(&tv_end, &tv_start, &tv_duration);
plink_ctx->sendid = (plink_ctx->sendid + 1) % NUM_OF_BUFFERS;
pthread_mutex_lock(&plink_ctx->mutex);
plink_ctx->available_bufs -= 1;
pthread_mutex_unlock(&plink_ctx->mutex);
}
else if (frame->img.type == CSI_IMG_TYPE_DMA_BUF && !plink_ctx->exitplink
&& plink_ctx->available_bufs > 0 && plink_ctx->plink != NULL && ((frame->img.pix_format == CSI_PIX_FMT_YUV_SEMIPLANAR_420)|| (frame->img.pix_format == CSI_PIX_FMT_NV12))) {
@@ -280,15 +330,13 @@ void display_camera_frame(void *plink, csi_frame_s *frame)
uint32_t dstw = frame->img.width;//800;
uint32_t dsth = frame->img.height;//1280;
uint32_t dsts = frame->img.strides[0];//896;
i++;
sprintf(str, "echo frame is %d > ~/frame", i);
system(str);
PlinkYuvInfo info = {0};
info.header.type = PLINK_TYPE_2D_YUV;
info.header.size = DATA_SIZE(info);
info.header.id = plink_ctx->sendid + 1;
info.header.id = plink_ctx->sendid;
info.format = PLINK_COLOR_FormatYUV420SemiPlanar;
// info.bus_address_y = vi_mem_import(frame->img.dmabuf[0].fds) + frame->img.dmabuf[0].offset;
@@ -306,16 +354,32 @@ void display_camera_frame(void *plink, csi_frame_s *frame)
pkt.list[0] = &info;
pkt.num = 1;
pkt.fd = frame->img.dmabuf[0].fds;
if(plink_ctx->frame_buf[plink_ctx->sendid].img.dmabuf[0].fds!=0)
{
LOG_W("previous sendid :%d,fd %d not release,release it now\n",plink_ctx->sendid,plink_ctx->frame_buf[plink_ctx->sendid].img.dmabuf[0].fds);
csi_camera_put_frame(&plink_ctx->frame_buf[plink_ctx->sendid]);
}
memcpy(&plink_ctx->frame_buf[plink_ctx->sendid],frame,sizeof(csi_frame_s));
plink_ctx->sendid = (plink_ctx->sendid + 1) % NUM_OF_BUFFERS;
if (PLINK_send(plink_ctx->plink, plink_ctx->chnid, &pkt) != PLINK_STATUS_OK)
plink_ctx->exitplink = 1;
gettimeofday(&tv_end, 0);
timersub(&tv_end, &tv_start, &tv_duration);
plink_ctx->sendid = (plink_ctx->sendid + 1) % NUM_OF_BUFFERS;
pthread_mutex_lock(&plink_ctx->mutex);
plink_ctx->available_bufs -= 1;
pthread_mutex_unlock(&plink_ctx->mutex);
} else if (!plink_ctx->exitplink && plink_ctx->available_bufs > 0 && plink_ctx->plink != NULL && (frame->img.pix_format == CSI_PIX_FMT_BGR)) {
CsiPictureBuffer *buf = &plink_ctx->sendbuffer[plink_ctx->sendid];
int y = 0;
// if (1) {
// void *pbuf[3];
// void *phyaddr = vi_mem_import(frame->img.dmabuf[0].fds);
// pbuf[0] = vi_mem_map(phyaddr) + frame->img.dmabuf[0].offset;
// pbuf[1] = pbuf[0] + frame->img.dmabuf[1].offset;
// vi_mem_release(phyaddr);
// frame->img.usr_addr[0] = pbuf[0];
// }
uint8_t *src = frame->img.usr_addr[0];
uint8_t *dst = buf->virtual_address;
uint32_t srcw = frame->img.width;
@@ -429,9 +493,10 @@ void display_camera_frame(void *plink, csi_frame_s *frame)
gettimeofday(&tv_end, 0);
timersub(&tv_end, &tv_start, &tv_duration);
pthread_mutex_lock(&plink_ctx->mutex);
plink_ctx->sendid = (plink_ctx->sendid + 1) % NUM_OF_BUFFERS;
plink_ctx->available_bufs -= 1;
pthread_mutex_unlock(&plink_ctx->mutex);
}
}
LOG_O("%s exit \n", __func__);

353
examples/camera/list.h Executable file
View File

@@ -0,0 +1,353 @@
/*
* Copyright © 2010 Intel Corporation
* Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
/* Modified by Ben Skeggs <bskeggs@redhat.com> to match kernel list APIs */
#ifndef _XORG_LIST_H_
#define _XORG_LIST_H_
/**
* @file Classic doubly-link circular list implementation.
* For real usage examples of the linked list, see the file test/list.c
*
* Example:
* We need to keep a list of struct foo in the parent struct bar, i.e. what
* we want is something like this.
*
* struct bar {
* ...
* struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
* ...
* }
*
* We need one list head in bar and a list element in all list_of_foos (both are of
* data type 'struct list_head').
*
* struct bar {
* ...
* struct list_head list_of_foos;
* ...
* }
*
* struct foo {
* ...
* struct list_head entry;
* ...
* }
*
* Now we initialize the list head:
*
* struct bar bar;
* ...
* INIT_LIST_HEAD(&bar.list_of_foos);
*
* Then we create the first element and add it to this list:
*
* struct foo *foo = malloc(...);
* ....
* list_add(&foo->entry, &bar.list_of_foos);
*
* Repeat the above for each element you want to add to the list. Deleting
* works with the element itself.
* list_del(&foo->entry);
* free(foo);
*
* Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
* list again.
*
* Looping through the list requires a 'struct foo' as iterator and the
* name of the field the subnodes use.
*
* struct foo *iterator;
* list_for_each_entry(iterator, &bar.list_of_foos, entry) {
* if (iterator->something == ...)
* ...
* }
*
* Note: You must not call list_del() on the iterator if you continue the
* loop. You need to run the safe for-each loop instead:
*
* struct foo *iterator, *next;
* list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
* if (...)
* list_del(&iterator->entry);
* }
*
*/
/**
* The linkage struct for list nodes. This struct must be part of your
* to-be-linked struct. struct list_head is required for both the head of the
* list and for each list node.
*
* Position and name of the struct list_head field is irrelevant.
* There are no requirements that elements of a list are of the same type.
* There are no requirements for a list head, any struct list_head can be a list
* head.
*/
struct list_head {
struct list_head *next, *prev;
};
/**
* Initialize the list as an empty list.
*
* Example:
* INIT_LIST_HEAD(&bar->list_of_foos);
*
* @param The list to initialized.
*/
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
static inline void
INIT_LIST_HEAD(struct list_head *list)
{
list->next = list->prev = list;
}
static inline void
__list_add(struct list_head *entry,
struct list_head *prev, struct list_head *next)
{
next->prev = entry;
entry->next = next;
entry->prev = prev;
prev->next = entry;
}
/**
* Insert a new element after the given list head. The new element does not
* need to be initialised as empty list.
* The list changes from:
* head → some element → ...
* to
* head → new element → older element → ...
*
* Example:
* struct foo *newfoo = malloc(...);
* list_add(&newfoo->entry, &bar->list_of_foos);
*
* @param entry The new element to prepend to the list.
* @param head The existing list.
*/
static inline void
list_add(struct list_head *entry, struct list_head *head)
{
__list_add(entry, head, head->next);
}
/**
* Append a new element to the end of the list given with this list head.
*
* The list changes from:
* head → some element → ... → lastelement
* to
* head → some element → ... → lastelement → new element
*
* Example:
* struct foo *newfoo = malloc(...);
* list_add_tail(&newfoo->entry, &bar->list_of_foos);
*
* @param entry The new element to prepend to the list.
* @param head The existing list.
*/
static inline void
list_add_tail(struct list_head *entry, struct list_head *head)
{
__list_add(entry, head->prev, head);
}
static inline void
__list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/**
* Remove the element from the list it is in. Using this function will reset
* the pointers to/from this element so it is removed from the list. It does
* NOT free the element itself or manipulate it otherwise.
*
* Using list_del on a pure list head (like in the example at the top of
* this file) will NOT remove the first element from
* the list but rather reset the list as empty list.
*
* Example:
* list_del(&foo->entry);
*
* @param entry The element to remove.
*/
static inline void
list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
static inline void
list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* Check if the list is empty.
*
* Example:
* list_empty(&bar->list_of_foos);
*
* @return True if the list contains one or more elements or False otherwise.
*/
static inline int
list_empty(struct list_head *head)
{
return head->next == head;
}
/**
* Returns a pointer to the container of this list element.
*
* Example:
* struct foo* f;
* f = container_of(&foo->entry, struct foo, entry);
* assert(f == foo);
*
* @param ptr Pointer to the struct list_head.
* @param type Data type of the list element.
* @param member Member name of the struct list_head field in the list element.
* @return A pointer to the data struct containing the list head.
*/
#ifndef container_of
#define container_of(ptr, type, member) \
(type *)((char *)(ptr) - (char *) &((type *)0)->member)
#endif
/**
* Alias of container_of
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* Retrieve the first list entry for the given list pointer.
*
* Example:
* struct foo *first;
* first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
*
* @param ptr The list head
* @param type Data type of the list element to retrieve
* @param member Member name of the struct list_head field in the list element.
* @return A pointer to the first list element.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* Retrieve the last list entry for the given listpointer.
*
* Example:
* struct foo *first;
* first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
*
* @param ptr The list head
* @param type Data type of the list element to retrieve
* @param member Member name of the struct list_head field in the list element.
* @return A pointer to the last list element.
*/
#define list_last_entry(ptr, type, member) \
list_entry((ptr)->prev, type, member)
#define __container_of(ptr, sample, member) \
(void *)container_of((ptr), typeof(*(sample)), member)
/**
* Loop through the list given by head and set pos to struct in the list.
*
* Example:
* struct foo *iterator;
* list_for_each_entry(iterator, &bar->list_of_foos, entry) {
* [modify iterator]
* }
*
* This macro is not safe for node deletion. Use list_for_each_entry_safe
* instead.
*
* @param pos Iterator variable of the type of the list elements.
* @param head List head
* @param member Member name of the struct list_head in the list elements.
*
*/
#define list_for_each_entry(pos, head, member) \
for (pos = __container_of((head)->next, pos, member); \
&pos->member != (head); \
pos = __container_of(pos->member.next, pos, member))
/**
* Loop through the list, keeping a backup pointer to the element. This
* macro allows for the deletion of a list element while looping through the
* list.
*
* See list_for_each_entry for more details.
*/
#define list_for_each_entry_safe(pos, tmp, head, member) \
for (pos = __container_of((head)->next, pos, member), \
tmp = __container_of(pos->member.next, pos, member); \
&pos->member != (head); \
pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = __container_of((head)->prev, pos, member); \
&pos->member != (head); \
pos = __container_of(pos->member.prev, pos, member))
#define list_for_each_entry_continue(pos, head, member) \
for (pos = __container_of(pos->member.next, pos, member); \
&pos->member != (head); \
pos = __container_of(pos->member.next, pos, member))
#define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = __container_of(pos->member.prev, pos, member); \
&pos->member != (head); \
pos = __container_of(pos->member.prev, pos, member))
#define list_for_each_entry_from(pos, head, member) \
for (; \
&pos->member != (head); \
pos = __container_of(pos->member.next, pos, member))
#endif

View File

@@ -102,7 +102,7 @@ int camera_destory_session(cams_t **session);
int camera_query_list(cams_t *session);
int camera_get_caps(cams_t *session);
int camera_open(cams_t *session, int cam_id);
int camera_open(cams_t *session, const char *dev_name);
int camera_close(cams_t *session);
int camera_get_modes(cams_t *session);

View File

@@ -48,7 +48,6 @@ static int _camera_session_reset(cams_t *session)
memset(session, 0, sizeof(*session));
session->state = CAMERA_STATE_CLOSED;
session->camera_id = -1;
session->camera_handle = NULL;
session->event_handle = NULL;
@@ -133,26 +132,24 @@ int camera_get_caps(cams_t *session)
return 0;
}
int camera_open(cams_t *session, int cam_id)
int camera_open(cams_t *session, const char *dev_name)
{
_CHECK_SESSION_RETURN();
int ret;
csi_camera_info_s camera_info;
csi_cam_handle_t handle;
if (!_get_info_status(session, CAMERA_INFOS_READY) ||
session->camera_infos.count <= cam_id) {
LOG_E("Can't open cam_id=%d\n", cam_id);
if (!_get_info_status(session, CAMERA_INFOS_READY)) {
LOG_E("Can't open %s\n", dev_name);
return -1;
}
char *dev_name = session->camera_infos.info[cam_id].device_name;
csi_cam_handle_t handle;
ret = csi_camera_open(&handle, dev_name);
if (ret != 0) {
LOG_E("Open camera(%s) failed\n", dev_name);
return -1;
}
session->camera_id = cam_id;
session->camera_handle = handle;
session->state = CAMERA_STATE_OPENED;
@@ -170,8 +167,6 @@ int camera_open(cams_t *session, int cam_id)
event_action = &(session->camera_event_action[i]);
event_action->target = MANAGE_TARGET_CAMERA;
event_action->camera_id = cam_id;
event_action->channel_id = -1;
event_action->camera.event = 1 << i;
//LOG_W("i=%d, event_action->camera.event=0x%08x\n", i, event_action->camera.event);
event_action->camera.supported = false;
@@ -196,8 +191,6 @@ int camera_open(cams_t *session, int cam_id)
event_action = &(session->channel_event_action[chn][i]);
event_action->target = MANAGE_TARGET_CHANNEL;
event_action->camera_id = cam_id;
event_action->channel_id = chn;
event_action->channel.event = 1 << i;
event_action->channel.supported = false;
event_action->channel.subscribed = false;
@@ -323,8 +316,8 @@ int camera_channel_query_list(cams_t *session)
}
ret = csi_camera_channel_query(session->camera_handle, &session->chn_cfg[i]);
if (ret != 0) {
LOG_E("Get %d channel configuration from camera[%d] failed\n",
i, session->camera_id);
LOG_E("Get %d channel configuration from camera[%s] failed\n",
i, session->camera_infos.info->device_name);
continue;
} else {
//LOG_D("channel[%d] status=%s\n", session->chn_cfg[i].chn_id,
@@ -436,7 +429,7 @@ int camera_subscribe_event(cams_t *session)
for (int chn = 0; chn < CSI_CAMERA_CHANNEL_MAX_COUNT; chn++) {
if (session->chn_cfg[chn].status != CSI_CAMERA_CHANNEL_OPENED) {
LOG_D("Camera[%d]:Channel[%d] is not OPENED\n", session->camera_id, chn);
LOG_D("Camera[%s]:Channel[%d] is not OPENED\n", session->camera_infos.info->device_name, chn);
continue;
}
for (int i = 0; i < CSI_CAMERA_CHANNEL_EVENT_MAX_COUNT; i++) {