int InitVideo (access_t *access, int fd, uint32_t caps) { access_sys_t *sys = access->p_sys; if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { msg_Err (access, "not a video capture device"); return -1; } v4l2_std_id std; if (SetupInput (VLC_OBJECT(access), fd, &std)) return -1; /* NOTE: The V4L access_demux expects a VLC FOURCC as "chroma". It is used to set the * es_format_t structure correctly. However, the V4L access (*here*) has no use for a * VLC FOURCC and expects a V4L2 format directly instead. That is confusing :-( */ uint32_t pixfmt = 0; char *fmtstr = var_InheritString (access, CFG_PREFIX"chroma"); if (fmtstr != NULL && strlen (fmtstr) <= 4) { memcpy (&pixfmt, fmtstr, strlen (fmtstr)); free (fmtstr); } else /* Use the default^Wprevious format if none specified */ { struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt) < 0) { msg_Err (access, "cannot get default format: %s", vlc_strerror_c(errno)); return -1; } pixfmt = fmt.fmt.pix.pixelformat; } msg_Dbg (access, "selected format %4.4s", (const char *)&pixfmt); struct v4l2_format fmt; struct v4l2_streamparm parm; if (SetupFormat (access, fd, pixfmt, &fmt, &parm)) return -1; msg_Dbg (access, "%"PRIu32" bytes for complete image", fmt.fmt.pix.sizeimage); /* Check interlacing */ switch (fmt.fmt.pix.field) { case V4L2_FIELD_INTERLACED: msg_Dbg (access, "Interlacing setting: interleaved"); /*if (NTSC) sys->block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST; else*/ sys->block_flags = BLOCK_FLAG_TOP_FIELD_FIRST; break; case V4L2_FIELD_INTERLACED_TB: msg_Dbg (access, "Interlacing setting: interleaved top bottom" ); sys->block_flags = BLOCK_FLAG_TOP_FIELD_FIRST; break; case V4L2_FIELD_INTERLACED_BT: msg_Dbg (access, "Interlacing setting: interleaved bottom top" ); sys->block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST; break; default: break; } /* Init I/O method */ if (caps & V4L2_CAP_STREAMING) { sys->bufc = 4; sys->bufv = StartMmap (VLC_OBJECT(access), fd, &sys->bufc); if (sys->bufv == NULL) return -1; access->pf_block = MMapBlock; } else if (caps & V4L2_CAP_READWRITE) { sys->blocksize = fmt.fmt.pix.sizeimage; sys->bufv = NULL; access->pf_block = ReadBlock; } else { msg_Err (access, "no supported capture method"); return -1; } return 0; }
int InitVideo (access_t *access, int fd, uint32_t caps) { access_sys_t *sys = access->p_sys; if (!(caps & V4L2_CAP_VIDEO_CAPTURE)) { msg_Err (access, "not a video capture device"); return -1; } if (SetupInput (VLC_OBJECT(access), fd)) return -1; sys->controls = ControlsInit (VLC_OBJECT(access), fd); /* Try and find default resolution if not specified */ struct v4l2_format fmt = { .type = V4L2_BUF_TYPE_VIDEO_CAPTURE }; if (v4l2_ioctl (fd, VIDIOC_G_FMT, &fmt) < 0) { msg_Err (access, "cannot get default format: %m"); return -1; } /* Print extra info */ msg_Dbg (access, "%d bytes maximum for complete image", fmt.fmt.pix.sizeimage ); /* Check interlacing */ switch (fmt.fmt.pix.field) { case V4L2_FIELD_INTERLACED: msg_Dbg (access, "Interlacing setting: interleaved"); /*if (NTSC) sys->block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST; else*/ sys->block_flags = BLOCK_FLAG_TOP_FIELD_FIRST; break; case V4L2_FIELD_INTERLACED_TB: msg_Dbg (access, "Interlacing setting: interleaved top bottom" ); sys->block_flags = BLOCK_FLAG_TOP_FIELD_FIRST; break; case V4L2_FIELD_INTERLACED_BT: msg_Dbg (access, "Interlacing setting: interleaved bottom top" ); sys->block_flags = BLOCK_FLAG_BOTTOM_FIELD_FIRST; break; default: break; } /* Init I/O method */ if (caps & V4L2_CAP_STREAMING) { sys->bufc = 4; sys->bufv = StartMmap (VLC_OBJECT(access), fd, &sys->bufc); if (sys->bufv == NULL) return -1; access->pf_block = AccessRead; } else if (caps & V4L2_CAP_READWRITE) { sys->blocksize = fmt.fmt.pix.sizeimage; sys->bufv = NULL; access->pf_read = AccessReadStream; } else { msg_Err (access, "no supported I/O method"); return -1; } return 0; }