summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2008-12-22 10:26:16 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2008-12-22 10:26:16 +0100
commit7b2085b575777d1fbcf93acd03a96ae307847611 (patch)
treeddd0684629abdbe23dce9c45fdff1167d8b41b1f
parent7702a6c7e30dab3cab062e385f503a06f2038271 (diff)
downloadvdr-7b2085b575777d1fbcf93acd03a96ae307847611.tar.gz
vdr-7b2085b575777d1fbcf93acd03a96ae307847611.tar.bz2
Changed cDvbDevice::GrabImage() to use V4L2
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY3
-rw-r--r--dvbdevice.c148
3 files changed, 94 insertions, 58 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 5de7402a..ff452acf 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1478,6 +1478,7 @@ Marco Schlüßler <marco@lordzodiac.de>
for a patch that was used to implement handling of DVB-S2
for fixing setting the date in the channel display of the classic and sttng skins,
to avoid unnecessary OSD access
+ for changing cDvbDevice::GrabImage() to use V4L2
Jürgen Schmitz <j.schmitz@web.de>
for reporting a bug in displaying the current channel when switching via the SVDRP
diff --git a/HISTORY b/HISTORY
index d2adef99..35a66b50 100644
--- a/HISTORY
+++ b/HISTORY
@@ -5849,9 +5849,10 @@ Video Disk Recorder Revision History
the patch from ftp://ftp.cadsoft.de/vdr/Developer/av7110_v4ldvb_api5_audiobuf_test_1.diff
to the driver (thanks to Oliver Endriss).
-2008-12-20: Version 1.7.3
+2008-12-22: Version 1.7.3
- Updated the Russian OSD texts (thanks to Oleg Roitburd).
- Fixed handling the 'pointer field' in generating and parsing PAT/PMT (thanks to
Frank Schmirler).
- Fixed handling modulation types for DVB-S transponders when processing the NIT.
+- Changed cDvbDevice::GrabImage() to use V4L2 (thanks to Marco Schlüßler).
diff --git a/dvbdevice.c b/dvbdevice.c
index e0b05a15..c3fe6868 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,13 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 2.6 2008/12/13 14:38:07 kls Exp $
+ * $Id: dvbdevice.c 2.7 2008/12/22 10:24:10 kls Exp $
*/
#include "dvbdevice.h"
#include <errno.h>
#include <limits.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/dvb/audio.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
@@ -604,69 +604,103 @@ uchar *cDvbDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int S
int videoDev = open(buffer, O_RDWR);
if (videoDev >= 0) {
uchar *result = NULL;
- struct video_mbuf mbuf;
- if (ioctl(videoDev, VIDIOCGMBUF, &mbuf) == 0) {
- int msize = mbuf.size;
- unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
- if (mem && mem != (unsigned char *)-1) {
- // set up the size and RGB
- struct video_capability vc;
- if (ioctl(videoDev, VIDIOCGCAP, &vc) == 0) {
- struct video_mmap vm;
- vm.frame = 0;
- if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
- (SizeY > 0) && (SizeY <= vc.maxheight)) {
- vm.width = SizeX;
- vm.height = SizeY;
- }
- else {
- vm.width = vc.maxwidth;
- vm.height = vc.maxheight;
- }
- vm.format = VIDEO_PALETTE_RGB24;
- if (ioctl(videoDev, VIDIOCMCAPTURE, &vm) == 0 && ioctl(videoDev, VIDIOCSYNC, &vm.frame) == 0) {
- // make RGB out of BGR:
- int memsize = vm.width * vm.height;
- unsigned char *mem1 = mem;
- for (int i = 0; i < memsize; i++) {
- unsigned char tmp = mem1[2];
- mem1[2] = mem1[0];
- mem1[0] = tmp;
- mem1 += 3;
- }
-
- if (Quality < 0)
- Quality = 100;
-
- dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
- if (Jpeg) {
- // convert to JPEG:
- result = RgbToJpeg(mem, vm.width, vm.height, Size, Quality);
- if (!result)
- esyslog("ERROR: failed to convert image to JPEG");
- }
- else {
- // convert to PNM:
- char buf[32];
- snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", vm.width, vm.height);
- int l = strlen(buf);
- int bytes = memsize * 3;
- Size = l + bytes;
- result = MALLOC(uchar, Size);
- if (result) {
- memcpy(result, buf, l);
- memcpy(result + l, mem, bytes);
+ // set up the size and RGB
+ v4l2_format fmt;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = SizeX;
+ fmt.fmt.pix.height = SizeY;
+ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
+ fmt.fmt.pix.field = V4L2_FIELD_ANY;
+ if (ioctl(videoDev, VIDIOC_S_FMT, &fmt) == 0) {
+ v4l2_requestbuffers reqBuf;
+ memset(&reqBuf, 0, sizeof(reqBuf));
+ reqBuf.count = 2;
+ reqBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ reqBuf.memory = V4L2_MEMORY_MMAP;
+ if (ioctl(videoDev, VIDIOC_REQBUFS, &reqBuf) >= 0) {
+ v4l2_buffer mbuf;
+ memset(&mbuf, 0, sizeof(mbuf));
+ mbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mbuf.memory = V4L2_MEMORY_MMAP;
+ if (ioctl(videoDev, VIDIOC_QUERYBUF, &mbuf) == 0) {
+ int msize = mbuf.length;
+ unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
+ if (mem && mem != (unsigned char *)-1) {
+ v4l2_buffer buf;
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = 0;
+ if (ioctl(videoDev, VIDIOC_QBUF, &buf) == 0) {
+ v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (ioctl (videoDev, VIDIOC_STREAMON, &type) == 0) {
+ memset(&buf, 0, sizeof(buf));
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = 0;
+ if (ioctl(videoDev, VIDIOC_DQBUF, &buf) == 0) {
+ if (ioctl(videoDev, VIDIOC_STREAMOFF, &type) == 0) {
+ // make RGB out of BGR:
+ int memsize = fmt.fmt.pix.width * fmt.fmt.pix.height;
+ unsigned char *mem1 = mem;
+ for (int i = 0; i < memsize; i++) {
+ unsigned char tmp = mem1[2];
+ mem1[2] = mem1[0];
+ mem1[0] = tmp;
+ mem1 += 3;
+ }
+
+ if (Quality < 0)
+ Quality = 100;
+
+ dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, fmt.fmt.pix.width, fmt.fmt.pix.height);
+ if (Jpeg) {
+ // convert to JPEG:
+ result = RgbToJpeg(mem, fmt.fmt.pix.width, fmt.fmt.pix.height, Size, Quality);
+ if (!result)
+ esyslog("ERROR: failed to convert image to JPEG");
+ }
+ else {
+ // convert to PNM:
+ char buf[32];
+ snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
+ int l = strlen(buf);
+ int bytes = memsize * 3;
+ Size = l + bytes;
+ result = MALLOC(uchar, Size);
+ if (result) {
+ memcpy(result, buf, l);
+ memcpy(result + l, mem, bytes);
+ }
+ else
+ esyslog("ERROR: failed to convert image to PNM");
+ }
+ }
+ else
+ esyslog("ERROR: video device VIDIOC_STREAMOFF failed");
+ }
+ else
+ esyslog("ERROR: video device VIDIOC_DQBUF failed");
}
else
- esyslog("ERROR: failed to convert image to PNM");
+ esyslog("ERROR: video device VIDIOC_STREAMON failed");
}
+ else
+ esyslog("ERROR: video device VIDIOC_QBUF failed");
+ munmap(mem, msize);
}
+ else
+ esyslog("ERROR: failed to memmap video device");
}
- munmap(mem, msize);
+ else
+ esyslog("ERROR: video device VIDIOC_QUERYBUF failed");
}
else
- esyslog("ERROR: failed to memmap video device");
+ esyslog("ERROR: video device VIDIOC_REQBUFS failed");
}
+ else
+ esyslog("ERROR: video device VIDIOC_S_FMT failed");
close(videoDev);
return result;
}