mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Changed cDvbDevice::GrabImage() to use V4L2
This commit is contained in:
parent
7702a6c7e3
commit
7b2085b575
@ -1478,6 +1478,7 @@ Marco Schl
|
|||||||
for a patch that was used to implement handling of DVB-S2
|
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,
|
for fixing setting the date in the channel display of the classic and sttng skins,
|
||||||
to avoid unnecessary OSD access
|
to avoid unnecessary OSD access
|
||||||
|
for changing cDvbDevice::GrabImage() to use V4L2
|
||||||
|
|
||||||
Jürgen Schmitz <j.schmitz@web.de>
|
Jürgen Schmitz <j.schmitz@web.de>
|
||||||
for reporting a bug in displaying the current channel when switching via the SVDRP
|
for reporting a bug in displaying the current channel when switching via the SVDRP
|
||||||
|
3
HISTORY
3
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
|
the patch from ftp://ftp.cadsoft.de/vdr/Developer/av7110_v4ldvb_api5_audiobuf_test_1.diff
|
||||||
to the driver (thanks to Oliver Endriss).
|
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).
|
- Updated the Russian OSD texts (thanks to Oleg Roitburd).
|
||||||
- Fixed handling the 'pointer field' in generating and parsing PAT/PMT (thanks to
|
- Fixed handling the 'pointer field' in generating and parsing PAT/PMT (thanks to
|
||||||
Frank Schmirler).
|
Frank Schmirler).
|
||||||
- Fixed handling modulation types for DVB-S transponders when processing the NIT.
|
- Fixed handling modulation types for DVB-S transponders when processing the NIT.
|
||||||
|
- Changed cDvbDevice::GrabImage() to use V4L2 (thanks to Marco Schlüßler).
|
||||||
|
144
dvbdevice.c
144
dvbdevice.c
@ -4,13 +4,13 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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 "dvbdevice.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/videodev.h>
|
#include <linux/videodev2.h>
|
||||||
#include <linux/dvb/audio.h>
|
#include <linux/dvb/audio.h>
|
||||||
#include <linux/dvb/dmx.h>
|
#include <linux/dvb/dmx.h>
|
||||||
#include <linux/dvb/frontend.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);
|
int videoDev = open(buffer, O_RDWR);
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
uchar *result = NULL;
|
uchar *result = NULL;
|
||||||
struct video_mbuf mbuf;
|
// set up the size and RGB
|
||||||
if (ioctl(videoDev, VIDIOCGMBUF, &mbuf) == 0) {
|
v4l2_format fmt;
|
||||||
int msize = mbuf.size;
|
memset(&fmt, 0, sizeof(fmt));
|
||||||
unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
|
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
if (mem && mem != (unsigned char *)-1) {
|
fmt.fmt.pix.width = SizeX;
|
||||||
// set up the size and RGB
|
fmt.fmt.pix.height = SizeY;
|
||||||
struct video_capability vc;
|
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
|
||||||
if (ioctl(videoDev, VIDIOCGCAP, &vc) == 0) {
|
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||||
struct video_mmap vm;
|
if (ioctl(videoDev, VIDIOC_S_FMT, &fmt) == 0) {
|
||||||
vm.frame = 0;
|
v4l2_requestbuffers reqBuf;
|
||||||
if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
|
memset(&reqBuf, 0, sizeof(reqBuf));
|
||||||
(SizeY > 0) && (SizeY <= vc.maxheight)) {
|
reqBuf.count = 2;
|
||||||
vm.width = SizeX;
|
reqBuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
vm.height = SizeY;
|
reqBuf.memory = V4L2_MEMORY_MMAP;
|
||||||
}
|
if (ioctl(videoDev, VIDIOC_REQBUFS, &reqBuf) >= 0) {
|
||||||
else {
|
v4l2_buffer mbuf;
|
||||||
vm.width = vc.maxwidth;
|
memset(&mbuf, 0, sizeof(mbuf));
|
||||||
vm.height = vc.maxheight;
|
mbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
}
|
mbuf.memory = V4L2_MEMORY_MMAP;
|
||||||
vm.format = VIDEO_PALETTE_RGB24;
|
if (ioctl(videoDev, VIDIOC_QUERYBUF, &mbuf) == 0) {
|
||||||
if (ioctl(videoDev, VIDIOCMCAPTURE, &vm) == 0 && ioctl(videoDev, VIDIOCSYNC, &vm.frame) == 0) {
|
int msize = mbuf.length;
|
||||||
// make RGB out of BGR:
|
unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
|
||||||
int memsize = vm.width * vm.height;
|
if (mem && mem != (unsigned char *)-1) {
|
||||||
unsigned char *mem1 = mem;
|
v4l2_buffer buf;
|
||||||
for (int i = 0; i < memsize; i++) {
|
memset(&buf, 0, sizeof(buf));
|
||||||
unsigned char tmp = mem1[2];
|
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
mem1[2] = mem1[0];
|
buf.memory = V4L2_MEMORY_MMAP;
|
||||||
mem1[0] = tmp;
|
buf.index = 0;
|
||||||
mem1 += 3;
|
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)
|
if (Quality < 0)
|
||||||
Quality = 100;
|
Quality = 100;
|
||||||
|
|
||||||
dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
|
dsyslog("grabbing to %s %d %d %d", Jpeg ? "JPEG" : "PNM", Quality, fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||||
if (Jpeg) {
|
if (Jpeg) {
|
||||||
// convert to JPEG:
|
// convert to JPEG:
|
||||||
result = RgbToJpeg(mem, vm.width, vm.height, Size, Quality);
|
result = RgbToJpeg(mem, fmt.fmt.pix.width, fmt.fmt.pix.height, Size, Quality);
|
||||||
if (!result)
|
if (!result)
|
||||||
esyslog("ERROR: failed to convert image to JPEG");
|
esyslog("ERROR: failed to convert image to JPEG");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// convert to PNM:
|
// convert to PNM:
|
||||||
char buf[32];
|
char buf[32];
|
||||||
snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", vm.width, vm.height);
|
snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
|
||||||
int l = strlen(buf);
|
int l = strlen(buf);
|
||||||
int bytes = memsize * 3;
|
int bytes = memsize * 3;
|
||||||
Size = l + bytes;
|
Size = l + bytes;
|
||||||
result = MALLOC(uchar, Size);
|
result = MALLOC(uchar, Size);
|
||||||
if (result) {
|
if (result) {
|
||||||
memcpy(result, buf, l);
|
memcpy(result, buf, l);
|
||||||
memcpy(result + l, mem, bytes);
|
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
|
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
|
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);
|
close(videoDev);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user