summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2005-12-29 14:51:59 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2005-12-29 14:51:59 +0100
commitcb428520e6f5cb7f5e56f4ba06f54b1ce7b47c23 (patch)
tree5ff205432bb58eaeb831ac9a789559a2bdb7a42b
parent5f7df33b1cabf1366eb414de1ac650c406d01ae3 (diff)
downloadvdr-cb428520e6f5cb7f5e56f4ba06f54b1ce7b47c23.tar.gz
vdr-cb428520e6f5cb7f5e56f4ba06f54b1ce7b47c23.tar.bz2
cDevice::GrabImage() now returns a pointer to the image in memory; cDevice::GrabImageFile() grabs the image to a file
-rw-r--r--HISTORY5
-rw-r--r--device.c33
-rw-r--r--device.h18
-rw-r--r--dvbdevice.c121
-rw-r--r--dvbdevice.h4
-rw-r--r--svdrp.c4
6 files changed, 105 insertions, 80 deletions
diff --git a/HISTORY b/HISTORY
index 00065c62..a486602f 100644
--- a/HISTORY
+++ b/HISTORY
@@ -4012,3 +4012,8 @@ Video Disk Recorder Revision History
extension (".jpg", ".jpeg" or ".pnm") of the given file name. The explicit
'jpeg' or 'pnm' parameter is still accepted for backward compatibility, but
has no meaning any more.
+- The function cDevice::GrabImage() no longer writes the grabbed image to a
+ file, but rather returns a pointer to the image in memory. The wrapper
+ function cDevice::GrabImageFile() can be used to write the grabbed image
+ directly to a file. Plugins that used the old version of cDevice::GrabImage()
+ need to be adapted to the new interface.
diff --git a/device.c b/device.c
index 1b4cec45..fb5360c8 100644
--- a/device.c
+++ b/device.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.c 1.112 2005/11/26 12:56:09 kls Exp $
+ * $Id: device.c 1.113 2005/12/29 14:51:41 kls Exp $
*/
#include "device.h"
@@ -322,9 +322,36 @@ void cDevice::Shutdown(void)
}
}
-bool cDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
+uchar *cDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
{
- return false;
+ return NULL;
+}
+
+bool cDevice::GrabImageFile(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
+{
+ int result = 0;
+ FILE *f = fopen(FileName, "wb");
+ if (f) {
+ int ImageSize;
+ uchar *Image = GrabImage(ImageSize, Jpeg, Quality, SizeX, SizeY);
+ if (Image) {
+ if (fwrite(Image, ImageSize, 1, f) == 1)
+ isyslog("grabbed image to %s", FileName);
+ else {
+ LOG_ERROR_STR(FileName);
+ result |= 1;
+ }
+ free(Image);
+ }
+ else
+ result |= 1;
+ fclose(f);
+ }
+ else {
+ LOG_ERROR_STR(FileName);
+ result |= 1;
+ }
+ return result == 0;
}
void cDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
diff --git a/device.h b/device.h
index 43d386bf..88607319 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 1.66 2005/11/05 15:25:41 kls Exp $
+ * $Id: device.h 1.67 2005/12/29 14:51:59 kls Exp $
*/
#ifndef __DEVICE_H
@@ -305,11 +305,9 @@ public:
// Image Grab facilities
public:
- virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
- ///< Capture a single frame as an image.
- ///< Grabs the currently visible screen image into the given file, with the
- ///< given parameters.
- ///< \param FileName The name of the file to write. Should include the proper extension.
+ virtual uchar *GrabImage(int &Size, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
+ ///< Grabs the currently visible screen image.
+ ///< \param Size The size of the returned data block.
///< \param Jpeg If true will write a JPEG file. Otherwise a PNM file will be written.
///< \param Quality The compression factor for JPEG. 1 will create a very blocky
///< and small image, 70..80 will yield reasonable quality images while keeping the
@@ -317,7 +315,13 @@ public:
///< but very high quality image.
///< \param SizeX The number of horizontal pixels in the frame (default is the current screen width).
///< \param SizeY The number of vertical pixels in the frame (default is the current screen height).
- ///< \return True if all went well. */
+ ///< \return A pointer to the grabbed image data, or NULL in case of an error.
+ ///< The caller takes ownership of the returned memory and must free() it once it isn't needed any more.
+ bool GrabImageFile(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
+ ///< Calls GrabImage() and stores the resulting image in a file with the given name.
+ ///< \return True if all went well.
+ ///< The caller is responsible for making sure that the given file name
+ ///< doesn't lead to overwriting any important other file.
// Video format facilities
diff --git a/dvbdevice.c b/dvbdevice.c
index 533a65ff..17b18cd1 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 1.142 2005/12/29 11:24:02 kls Exp $
+ * $Id: dvbdevice.c 1.143 2005/12/29 13:49:09 kls Exp $
*/
#include "dvbdevice.h"
@@ -480,95 +480,84 @@ cSpuDecoder *cDvbDevice::GetSpuDecoder(void)
return spuDecoder;
}
-bool cDvbDevice::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
+uchar *cDvbDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
{
if (devVideoIndex < 0)
- return false;
+ return NULL;
char buffer[PATH_MAX];
snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, devVideoIndex);
int videoDev = open(buffer, O_RDWR);
- if (videoDev < 0)
- LOG_ERROR_STR(buffer);
if (videoDev >= 0) {
- int result = 0;
+ uchar *result = NULL;
struct video_mbuf mbuf;
- result |= ioctl(videoDev, VIDIOCGMBUF, &mbuf);
- if (result == 0) {
+ 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;
- result |= ioctl(videoDev, VIDIOCGCAP, &vc);
- 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;
- result |= ioctl(videoDev, VIDIOCMCAPTURE, &vm);
- result |= ioctl(videoDev, VIDIOCSYNC, &vm.frame);
- // 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 (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;
-
- isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
- FILE *f = fopen(FileName, "wb");
- if (f) {
- if (Jpeg) {
- // write JPEG file:
- int JpegImageSize;
- uchar *JpegImage = RgbToJpeg(mem, vm.width, vm.height, JpegImageSize, Quality);
- if (JpegImage) {
- if (fwrite(JpegImage, JpegImageSize, 1, f) != 1) {
- LOG_ERROR_STR(FileName);
- result |= 1;
- }
- delete JpegImage;
+ if (Quality < 0)
+ Quality = 100;
+
+ isyslog("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 {
- esyslog("ERROR: failed to convert image to JPEG");
- result |= 1;
- }
- }
- else {
- // write PNM file:
- if (fprintf(f, "P6\n%d\n%d\n255\n", vm.width, vm.height) < 0 ||
- fwrite(mem, vm.width * vm.height * 3, 1, f) != 1) {
- LOG_ERROR_STR(FileName);
- result |= 1;
+ // 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);
+ }
+ else
+ esyslog("ERROR: failed to convert image to PNM");
}
}
- fclose(f);
- }
- else {
- LOG_ERROR_STR(FileName);
- result |= 1;
}
munmap(mem, msize);
}
else
- result |= 1;
+ esyslog("ERROR: failed to memmap video device");
}
close(videoDev);
- return result == 0;
+ return result;
}
- return false;
+ else
+ LOG_ERROR_STR(buffer);
+ return NULL;
}
void cDvbDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
diff --git a/dvbdevice.h b/dvbdevice.h
index ed0cef8a..cc9d126a 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.h 1.36 2005/11/11 14:51:38 kls Exp $
+ * $Id: dvbdevice.h 1.37 2005/12/29 13:33:12 kls Exp $
*/
#ifndef __DVBDEVICE_H
@@ -85,7 +85,7 @@ private:
static int devVideoOffset;
int devVideoIndex;
public:
- virtual bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
+ virtual uchar *GrabImage(int &Size, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
// Video format facilities
diff --git a/svdrp.c b/svdrp.c
index c6b557b9..91b39518 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 1.85 2005/12/29 12:17:27 kls Exp $
+ * $Id: svdrp.c 1.86 2005/12/29 13:33:43 kls Exp $
*/
#include "svdrp.h"
@@ -711,7 +711,7 @@ void cSVDRP::CmdGRAB(const char *Option)
Reply(501, "Unexpected parameter \"%s\"", p);
return;
}
- if (cDevice::PrimaryDevice()->GrabImage(FileName, Jpeg, Quality, SizeX, SizeY))
+ if (cDevice::PrimaryDevice()->GrabImageFile(FileName, Jpeg, Quality, SizeX, SizeY))
Reply(250, "Grabbed image %s", Option);
else
Reply(451, "Grab image failed");