⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vidinput_v4l2.cxx

📁 安装 H323需要的pwlib库
💻 CXX
📖 第 1 页 / 共 2 页
字号:
  struct v4l2_requestbuffers reqbuf;  reqbuf.count = 1; // we shouldn't need more  reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  reqbuf.memory = V4L2_MEMORY_MMAP;  if (::ioctl(videoFd, VIDIOC_REQBUFS, &reqbuf) < 0 ||      reqbuf.count < 1 ||      reqbuf.count > NUM_VIDBUF) {    PTRACE(3,"PVidInDev\tREQBUFS failed : " << ::strerror(errno));    return FALSE;  }  struct v4l2_buffer buf;  memset(&buf, 0, sizeof(buf));  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    videoBufferCount = reqbuf.count;  for (buf.index = 0; buf.index < videoBufferCount; buf.index++) {    if (::ioctl(videoFd, VIDIOC_QUERYBUF, &buf) < 0) {      PTRACE(3,"PVidInDev\tQUERYBUF failed : " << ::strerror(errno));      return FALSE;    }    if ((videoBuffer[buf.index] = (BYTE *)::mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, videoFd, buf.m.offset)) == MAP_FAILED) {      PTRACE(3,"PVidInDev\tmmap failed : " << ::strerror(errno));      return FALSE;    }  }  isMapped = TRUE;  PTRACE(7,"PVidInDev\tset mapping for " << videoBufferCount << " buffers, fd=" << videoFd);  return TRUE;}void PVideoInputV4l2Device::ClearMapping(){  if (!canStream) // 'isMapped' wouldn't handle partial mappings    return;  struct v4l2_buffer buf;  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  for (buf.index = 0; ; buf.index++) {    if (::ioctl(videoFd, VIDIOC_QUERYBUF, &buf) < 0)      break;    ::munmap(videoBuffer[buf.index], buf.length);  }  isMapped = FALSE;  PTRACE(7,"PVidInDev\tclear mapping, fd=" << videoFd);}BOOL PVideoInputV4l2Device::GetFrame(PBYTEArray & frame){  PINDEX returned;  if (!GetFrameData(frame.GetPointer(GetMaxFrameBytes()), &returned))    return FALSE;  frame.SetSize(returned);  return TRUE;}BOOL PVideoInputV4l2Device::GetFrameData(BYTE * buffer, PINDEX * bytesReturned){  PTRACE(1,"PVidInDev\tGetFrameData()");  if (frameRate>0) {    PTimeInterval delay;    do {      if (!GetFrameDataNoDelay(buffer, bytesReturned))	return FALSE;      delay = PTime() - previousFrameTime;    } while (delay.GetMilliSeconds() < msBetweenFrames);    previousFrameTime = PTime();    return TRUE;  }  return GetFrameDataNoDelay(buffer, bytesReturned);}BOOL PVideoInputV4l2Device::GetFrameDataNoDelay(BYTE * buffer, PINDEX * bytesReturned){  PTRACE(1,"PVidInDev\tGetFrameDataNoDelay()\tstarted:" << started << "  canSelect:" << canSelect);  if (!started)    return NormalReadProcess(buffer, bytesReturned);  struct v4l2_buffer buf;  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  buf.index = 0;  if (::ioctl(videoFd, VIDIOC_DQBUF, &buf) < 0) {    PTRACE(1,"PVidInDev\tDQBUF failed : " << ::strerror(errno));    return FALSE;  }  // If converting on the fly do it from frame store to output buffer,  // otherwise do straight copy.  if (converter != NULL)    converter->Convert(videoBuffer[buf.index], buffer, bytesReturned);  else {    memcpy(buffer, videoBuffer[buf.index], buf.bytesused);    if (bytesReturned != NULL)      *bytesReturned = buf.bytesused;  }  PTRACE(8,"PVidInDev\tget frame data of " << buf.bytesused << "bytes, fd=" << videoFd);  // requeue the buffer  if (::ioctl(videoFd, VIDIOC_QBUF, &buf) < 0) {    PTRACE(1,"PVidInDev\tQBUF failed : " << ::strerror(errno));  }  return TRUE;}// This video device does not support memory mapping - so use// normal read process to extract a frame of video data.BOOL PVideoInputV4l2Device::NormalReadProcess(BYTE * buffer, PINDEX * bytesReturned){   if (!canRead)    return FALSE;  ssize_t bytesRead;  do    bytesRead = ::read(videoFd, buffer, frameBytes);  while (bytesRead < 0 && errno == EINTR);  if (bytesRead < 0) {        PTRACE(1,"PVidInDev\tread failed (read = "<<bytesRead<< " expected " << frameBytes <<")");    bytesRead = frameBytes;  }  if ((PINDEX)bytesRead != frameBytes) {    PTRACE(1,"PVidInDev\tread returned fewer bytes than expected");    // May result from a compressed format, otherwise indicates an error.  }  if (converter != NULL)    return converter->ConvertInPlace(buffer, bytesReturned);  if (bytesReturned != NULL)    *bytesReturned = (PINDEX)bytesRead;  return TRUE;}BOOL PVideoInputV4l2Device::VerifyHardwareFrameSize(unsigned width,						    unsigned height){  struct v4l2_format videoFormat;  videoFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;  // get the frame size  if (::ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) {    PTRACE(1,"PVidInDev\tG_FMT failed : " << ::strerror(errno));    return FALSE;  }  videoFormat.fmt.pix.width = width;  videoFormat.fmt.pix.height = height;  // set the frame size  if (::ioctl(videoFd, VIDIOC_S_FMT, &videoFormat) < 0) {    PTRACE(1,"PVidInDev\tS_FMT failed : " << ::strerror(errno));    PTRACE(1,"\tused frame size of " << videoFormat.fmt.pix.width << "x" << videoFormat.fmt.pix.height);    return FALSE;  }  // get the frame size again to be careful about broken drivers  if (::ioctl(videoFd, VIDIOC_G_FMT, &videoFormat) < 0) {    PTRACE(1,"PVidInDev\tG_FMT failed : " << ::strerror(errno));    return FALSE;  }  if ((videoFormat.fmt.pix.width != width) || (videoFormat.fmt.pix.height != height)) {    PTRACE(3,"PVidInDev\tframe size mismatch.");    // allow the device to return actual frame size    PVideoDevice::SetFrameSize(videoFormat.fmt.pix.width, videoFormat.fmt.pix.height);    return FALSE;  }  frameBytes = videoFormat.fmt.pix.sizeimage;  return TRUE;}int PVideoInputV4l2Device::GetBrightness() {   if (!IsOpen())    return -1;  struct v4l2_control c;  c.id = V4L2_CID_BRIGHTNESS;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    return -1;  frameBrightness = c.value;  return frameBrightness; }int PVideoInputV4l2Device::GetWhiteness() {   if (!IsOpen())    return -1;  struct v4l2_control c;  c.id = V4L2_CID_WHITENESS;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    return -1;  frameWhiteness = c.value;  return frameWhiteness;}int PVideoInputV4l2Device::GetColour() {   if (!IsOpen())    return -1;  struct v4l2_control c;  c.id = V4L2_CID_SATURATION;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    return -1;  frameColour = c.value;  return frameColour; }int PVideoInputV4l2Device::GetContrast() {  if (!IsOpen())    return -1;  struct v4l2_control c;  c.id = V4L2_CID_CONTRAST;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    return -1;  frameContrast = c.value;  return frameContrast; }int PVideoInputV4l2Device::GetHue() {  if (!IsOpen())    return -1;  struct v4l2_control c;  c.id = V4L2_CID_HUE;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    return -1;  frameHue = c.value;  return frameHue; }BOOL PVideoInputV4l2Device::SetBrightness(unsigned newBrightness) {   if (!IsOpen())    return FALSE;  struct v4l2_queryctrl q;  q.id = V4L2_CID_BRIGHTNESS;  if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0)    return FALSE;  struct v4l2_control c;  c.id = V4L2_CID_BRIGHTNESS;  c.value = q.minimum + ((q.maximum-q.minimum) * newBrightness) >> 16;  if (::ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0)    return FALSE;  frameBrightness = newBrightness;  return TRUE;}BOOL PVideoInputV4l2Device::SetWhiteness(unsigned newWhiteness) {   if (!IsOpen())    return FALSE;  struct v4l2_queryctrl q;  q.id = V4L2_CID_WHITENESS;  if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0)    return FALSE;  struct v4l2_control c;  c.id = V4L2_CID_WHITENESS;  c.value = q.minimum + ((q.maximum-q.minimum) * newWhiteness) >> 16;  if (::ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0)    return FALSE;  frameWhiteness = newWhiteness;  return TRUE;}BOOL PVideoInputV4l2Device::SetColour(unsigned newColour) {   if (!IsOpen())    return FALSE;  struct v4l2_queryctrl q;  q.id = V4L2_CID_SATURATION;  if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0)    return FALSE;  struct v4l2_control c;  c.id = V4L2_CID_SATURATION;  c.value = q.minimum + ((q.maximum-q.minimum) * newColour) >> 16;  if (::ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0)    return FALSE;  frameColour = newColour;  return TRUE;}BOOL PVideoInputV4l2Device::SetContrast(unsigned newContrast) {   if (!IsOpen())    return FALSE;  struct v4l2_queryctrl q;  q.id = V4L2_CID_CONTRAST;  if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0)    return FALSE;  struct v4l2_control c;  c.id = V4L2_CID_CONTRAST;  c.value = q.minimum + ((q.maximum-q.minimum) * newContrast) >> 16;  if (::ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0)    return FALSE;  frameContrast = newContrast;  return TRUE;}BOOL PVideoInputV4l2Device::SetHue(unsigned newHue) {  if (!IsOpen())    return FALSE;  struct v4l2_queryctrl q;  q.id = V4L2_CID_HUE;  if (::ioctl(videoFd, VIDIOC_QUERYCTRL, &q) < 0)    return FALSE;  struct v4l2_control c;  c.id = V4L2_CID_HUE;  c.value = q.minimum + ((q.maximum-q.minimum) * newHue) >> 16;  if (::ioctl(videoFd, VIDIOC_S_CTRL, &c) < 0)    return FALSE;  frameHue=newHue;  return TRUE;}BOOL PVideoInputV4l2Device::GetParameters (int *whiteness, int *brightness, 					   int *colour, int *contrast, int *hue){  if (!IsOpen())    return FALSE;  struct v4l2_control c;  c.id = V4L2_CID_WHITENESS;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    frameWhiteness = -1;  else    frameWhiteness = c.value;  c.id = V4L2_CID_BRIGHTNESS;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    frameBrightness = -1;  else    frameBrightness = c.value;  c.id = V4L2_CID_SATURATION;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    frameColour = -1;  else    frameColour = c.value;  c.id = V4L2_CID_CONTRAST;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    frameContrast = -1;  else    frameContrast = c.value;  c.id = V4L2_CID_HUE;  if (::ioctl(videoFd, VIDIOC_G_CTRL, &c) < 0)    frameHue = -1;  else    frameHue = c.value;  *whiteness  = frameWhiteness;  *brightness = frameBrightness;  *colour     = frameColour;  *contrast   = frameContrast;  *hue        = frameHue;  return TRUE;}BOOL PVideoInputV4l2Device::TestAllFormats(){  return TRUE;}// this is used to get more userfriendly names:voidV4L2Names::Update(){  PTRACE(1,"Detecting V4L2 devices");  PDirectory   procvideo2_4("/proc/video/dev");  PDirectory   procvideo2_6("/sys/class/video4linux");  PDirectory * procvideo;  PString      entry;  PStringList  devlist;  PString      oldDevName;  // Try and guess kernel version  if (procvideo2_6.Exists()) {    kernelVersion = K2_6;    procvideo=&procvideo2_6;  }  else if (procvideo2_4.Exists()) {    kernelVersion=K2_4;    procvideo=&procvideo2_4;  }   else {    kernelVersion=KUNKNOWN;    procvideo=0;  }  inputDeviceNames.RemoveAll (); // flush the previous run  if (procvideo) {    PTRACE(2,"PV4L2Plugin\tdetected device metadata at "<<*procvideo);    if ((kernelVersion==K2_6 && procvideo->Open(PFileInfo::SubDirectory) || 	 (procvideo->Open(PFileInfo::RegularFile)))) {      do {        entry = procvideo->GetEntryName();	if ((entry.Left(5) == "video")) {	  PString thisDevice = "/dev/" + entry;	  int videoFd=::open((const char *)thisDevice, O_RDONLY | O_NONBLOCK);	  if ((videoFd > 0) || (errno == EBUSY)) {	    BOOL valid = FALSE;	    struct v4l2_capability videoCaps;	    memset(&videoCaps,0,sizeof(videoCaps));	    if ((errno == EBUSY) ||		(::ioctl(videoFd, VIDIOC_QUERYCAP, &videoCaps) >= 0 &&		 (videoCaps.capabilities & V4L2_CAP_VIDEO_CAPTURE))) {	      PTRACE(1,"PV4L2Plugin\tdetected capture device " << videoCaps.card);	      valid = TRUE;	    }	    else {	      PTRACE(1,"PV4L2Plugin\t" << thisDevice << "is not deemed valid");	    }	    if (videoFd>0)	      ::close(videoFd);	    if(valid)	      inputDeviceNames += thisDevice;	  }	  else {	    PTRACE(1,"PV4L2Plugin\tcould not open " << thisDevice);	  }	}      } while (procvideo->Next());    }  }  else {    PTRACE(1,"Unable to detect v4l2 directory");  }  if (inputDeviceNames.GetSize() == 0) {    POrdinalToString vid;    ReadDeviceDirectory("/dev/", vid);    for (PINDEX i = 0; i < vid.GetSize(); i++) {      PINDEX cardnum = vid.GetKeyAt(i);      int fd = ::open(vid[cardnum], O_RDONLY | O_NONBLOCK);      if ((fd >= 0) || (errno == EBUSY)) {	if (fd >= 0)	  ::close(fd);	inputDeviceNames += vid[cardnum];      }    }  }  PopulateDictionary();}PString V4L2Names::BuildUserFriendly(PString devname){  PString Result;  int fd = ::open((const char *)devname, O_RDONLY);  if(fd < 0) {    return devname;  }  struct v4l2_capability videocap;  memset(&videocap,0,sizeof(videocap));  if (::ioctl(fd, VIDIOC_QUERYCAP, &videocap) < 0)  {      ::close(fd);      return devname;    }    ::close(fd);  PString ufname((const char*)videocap.card);  return ufname;}// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -