Android系統Camera預覽剛開啟時由暗變明

2021-06-19 10:04:09 字數 4122 閱讀 1114

一、回憶下v4l2驅動操作流程

1.查詢驅動功能

struct v4l2_capability cap;  

ioctl(fd,vidioc_querycap,&cap);

printf("tk---------->>>>>driver name:%s\ncard name:%s\nbus info:%s\n",cap.driver,cap.card,cap.bus_info);

struct v4l2_fmtdesc fmtdesc;  

fmtdesc.index = 0; fmtdesc.type = v4l2_buf_type_video_capture;

while(ioctl(fd,vidioc_enum_fmt,&fmtdesc) != -1)

3.設定當前驅動的頻捕獲格式

struct v4l2_format fmt;  

memset(&fmt,0,sizeof(fmt));

fmt.type = v4l2_buf_type_video_capture;

fmt.fmt.pix.width = 1280;

fmt.fmt.pix.height = 720;

fmt.fmt.pix.pixelformat = v4l2_pix_fmt_mjpeg;

fmt.fmt.pix.field = v4l2_field_none;//v4l2_field_interlaced;

fmt.fmt.pix.colorspace = 8;

int fmtreslt = ioctl(fd,vidioc_s_fmt,&fmt);

printf("tk--------_>>>>fmtreslt is %d\n",fmtreslt);

fmt.type = v4l2_buf_type_video_capture;

//重新獲取,看是否設定成功

ioctl(fd,vidioc_g_fmt,&fmt);

printf("tk----------->>>>>fmt.fmt.width is %d\nfmt.fmt.pix.height is %d\nfmt.fmt.pix.colorspace is %d\n",fmt.fmt.pix.width,fmt.fmt.pix.height,fmt.fmt.pix.colorspace);

4.分配記憶體(一般不超過5個)並轉換成實體地址,將物理位址對映到使用者空間

struct v4l2_requestbuffers req;  

req.count = 4;

req.type = v4l2_buf_type_video_capture;

req.memory = v4l2_memory_mmap;

//分配記憶體

ioctl(fd,vidioc_reqbufs,&req);

struct buffer*buffers;

buffers = (struct buffer*)calloc (req.count, sizeof(*buffers));

unsigned int n_buffers = 0;

for(n_buffers = 0; n_buffers < req.count; ++n_buffers)

buffers[n_buffers].length = buf.length;

//對映到使用者空間

buffers[n_buffers].start = mmap(null,buf.length,prot_read|prot_write,map_shared,fd,buf.m.offset);

if(map_failed == buffers[n_buffers].start)

}

5.把資料放入快取佇列

unsigned int i;  

enum v4l2_buf_type type;

for(i = 0; i < 4; i++)

type = v4l2_buf_type_video_capture;  

ioctl(fd,vidioc_streamon,&type);

7.把資料從快取佇列中讀取出來
unsigned int j;  

for(j = 0; j < 4; j++)

ioctl(fd,vidioc_streamoff,&type);
二、修改

原來如下——

ioctl(fd,vidioc_qbuf,&buf); 

ioctl(fd,vidioc_streamon,&type);

ioctl(fd,vidioc_dqbuf,&buf);

現在改為——

ioctl(fd,vidioc_streamon,&type);

usleep(800000);

ioctl(fd,vidioc_qbuf,&buf);

ioctl(fd,vidioc_dqbuf,&buf);

其實就是剛開啟時的資料不能要!!!!!

三、工程例項

status_t v4lcameraadapter::startpreview()

#endif

ret = ioctl(mcamerahandle, vidioc_qbuf, &mvideoinfo->buf);

if (ret < 0)

camhal_logdb("startpreview --length=%d, index:%d", mvideoinfo->buf.length,mvideoinfo->buf.index);

nqueued++;

}*///end tankai

enum v4l2_buf_type buftype;

if (!mvideoinfo->isstreaming)

mvideoinfo->isstreaming = true;

}if( menablecontifocus &&

(cam_focus_mode_auto != cur_focus_mode_for_conti) &&

(cam_focus_mode_infinity != cur_focus_mode_for_conti))

cur_focus_mode_for_conti = cam_focus_mode_conti_vid;

}//add by tankai

usleep(800000);

nqueued = 0;

for (int i = 0; i < mpreviewbuffercount; i++)

#endif

ret = ioctl(mcamerahandle, vidioc_qbuf, &mvideoinfo->buf);

if (ret < 0)

camhal_logdb("startpreview --length=%d, index:%d", mvideoinfo->buf.length,mvideoinfo->buf.index);

nqueued++;

}//end tankai

......

}

補充:

看看preview執行緒:

int v4lcameraadapter::previewthread()

*/} char *fp = this->getframe(index);

/*char * v4lcameraadapter::getframe(int &index)

*/

uint8_t* src = (uint8_t*) fp; //camera原始資料

private_handle_t* gralloc_hnd = (private_handle_t*)ptr;

dest = (uint8_t*)gralloc_hnd->base;

if(default_preview_pixel_format == v4l2_pix_fmt_yuyv)

}

Android 呼叫系統Camera

在android中應用相機功能,一般有兩種 一種是直接呼叫系統相機,一種自己寫的相機。我將分別演示兩種方式的使用 第一種 是使用intent跳轉到系統相機,action為 android.media.action.still image camera import import android.co...

Android平台硬體除錯之Camera篇

之前一段時間有幸在高通android平台上除錯2款camera sensor,一款是ov的5m yuv sensor,支援jpeg out,同時也支援af,除錯比較比較簡單,因為別的專案已經在使用了,只是把相關的驅動移植過來就好 另一款是samsung的一款比較新的3m yuv ff sensor,...

Android動態申請Camera許可權應用閃退問題

final int result permissionsstate.grantruntimepermission bp,userid switch result case permissionsstate.permission operation success gids changed break...