omap3isp上层应用解析
代码仓库位置:
https://git.ideasonboard.org/
仓库包含几个项目:
- media-ctl
- media-enum
- omap3-isp-dsp
- omap3-isp-live
本文从omap3-isp-dsp入手分析上层应用中media的使用流程。
main入口函数
omap3-isp-dsp/isp-dsp.c
int main(int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__)))
{
struct omap3_dsp_device dsp;
struct omap3_isp_device isp;
struct timespec start, end;
unsigned int count = 0;
int exit_code = EXIT_FAILURE;
float fps;
int ret;
/* Register a signal handler for SIGINT, received when the user presses
* CTRL-C. This will allow the main loop to be interrupted, and resources
* to be freed cleanly.
*/
signal(SIGINT, sigint_handler);
memset(&dsp, 0, sizeof dsp);
memset(&isp, 0, sizeof isp);
/* Open the media device and setup the capture pipeline. The pipeline
* topology is hardcoded to sensor -> CCDC -> CCDC output.
*/
/*
原英文注释已经很清楚:sensor输出视频-》CCDC接收-》CCDC输出数据到内存(可能用于LCD显示等)。
media是本文的重点分析。
*/
isp.mdev = media_open(MEDIA_DEVICE, 0);
if (isp.mdev == NULL) {
printf("error: unable to open media device %s\n", MEDIA_DEVICE);
goto cleanup;
}
ret = omap3isp_pipeline_setup(&isp);//建立pipeline,重点2
if (ret < 0) {
printf("error: unable to setup pipeline\n");
goto cleanup;
}
/* Open the video capture device, setup the format and allocate the
* buffers.
*/
isp.vdev = v4l2_open(isp.video->devname);//V4L2的流程在此不关心
if (isp.vdev == NULL) {
printf("error: unable to open video capture device %s\n",
isp.video->devname);
goto cleanup;
}
ret = omap3isp_video_setup(&isp);
if (ret < 0) {
printf("error: unable to setup video capture\n");
goto cleanup;
}
/* Initialize the DSP. */
ret = omap3dsp_setup(&dsp, isp.vdev->buffers);
if (ret < 0) {
printf("error: unable to setup DSP\n");
goto cleanup;
}
/* Start the DSP and ISP. */
ret = omap3dsp_start(&dsp);
if (ret < 0)
goto cleanup;
ret = omap3isp_video_start(&isp);
if (ret < 0)
goto cleanup;
clock_gettime(CLOCK_MONOTONIC, &start);
/* Main capture loop. Wait for a video buffer using select() and process
* it.
*/
while (!done) {
struct timeval timeout;
fd_set rfds;
timeout.tv_sec = SELECT_TIMEOUT / 1000;
timeout.tv_usec = (SELECT_TIMEOUT % 1000) * 1000;
rfds = isp.fds;
ret = select(isp.vdev->fd + 1, &rfds, NULL, NULL, &timeout);
if (ret < 0) {
/* EINTR means that a signal has been received, continue
* to the next iteration in that case.
*/
if (errno == EINTR)
continue;
printf("error: select failed with %d\n", errno);
goto cleanup;
}
if (ret == 0) {
/* select() should never time out as the ISP is supposed
* to capture images continuously. A timeout is thus
* considered as a fatal error.
*/
printf("error: select timeout\n");
goto cleanup;
}
process_image(&isp, &dsp);
count++;
}
clock_gettime(CLOCK_MONOTONIC, &end);