cDevice::GrabImage() now returns a pointer to the image in memory; cDevice::GrabImageFile() grabs the image to a file

This commit is contained in:
Klaus Schmidinger 2005-12-29 14:51:59 +01:00
parent 5f7df33b1c
commit cb428520e6
6 changed files with 106 additions and 81 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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 (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;
}
else {
esyslog("ERROR: failed to convert image to JPEG");
result |= 1;
}
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 {
// 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;
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 %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);
}
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)

View File

@ -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

View File

@ -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");