mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
cDevice::GrabImage() now returns a pointer to the image in memory; cDevice::GrabImageFile() grabs the image to a file
This commit is contained in:
parent
5f7df33b1c
commit
cb428520e6
5
HISTORY
5
HISTORY
@ -4012,3 +4012,8 @@ Video Disk Recorder Revision History
|
|||||||
extension (".jpg", ".jpeg" or ".pnm") of the given file name. The explicit
|
extension (".jpg", ".jpeg" or ".pnm") of the given file name. The explicit
|
||||||
'jpeg' or 'pnm' parameter is still accepted for backward compatibility, but
|
'jpeg' or 'pnm' parameter is still accepted for backward compatibility, but
|
||||||
has no meaning any more.
|
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.
|
||||||
|
33
device.c
33
device.c
@ -4,7 +4,7 @@
|
|||||||
* 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: 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"
|
#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)
|
void cDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
|
||||||
|
18
device.h
18
device.h
@ -4,7 +4,7 @@
|
|||||||
* 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: 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
|
#ifndef __DEVICE_H
|
||||||
@ -305,11 +305,9 @@ public:
|
|||||||
// Image Grab facilities
|
// Image Grab facilities
|
||||||
|
|
||||||
public:
|
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);
|
||||||
///< Capture a single frame as an image.
|
///< Grabs the currently visible screen image.
|
||||||
///< Grabs the currently visible screen image into the given file, with the
|
///< \param Size The size of the returned data block.
|
||||||
///< given parameters.
|
|
||||||
///< \param FileName The name of the file to write. Should include the proper extension.
|
|
||||||
///< \param Jpeg If true will write a JPEG file. Otherwise a PNM file will be written.
|
///< \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
|
///< \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
|
///< and small image, 70..80 will yield reasonable quality images while keeping the
|
||||||
@ -317,7 +315,13 @@ public:
|
|||||||
///< but very high quality image.
|
///< but very high quality image.
|
||||||
///< \param SizeX The number of horizontal pixels in the frame (default is the current screen width).
|
///< \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).
|
///< \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
|
// Video format facilities
|
||||||
|
|
||||||
|
123
dvbdevice.c
123
dvbdevice.c
@ -4,7 +4,7 @@
|
|||||||
* 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 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"
|
#include "dvbdevice.h"
|
||||||
@ -480,95 +480,84 @@ cSpuDecoder *cDvbDevice::GetSpuDecoder(void)
|
|||||||
return spuDecoder;
|
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)
|
if (devVideoIndex < 0)
|
||||||
return false;
|
return NULL;
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, devVideoIndex);
|
snprintf(buffer, sizeof(buffer), "%s%d", DEV_VIDEO, devVideoIndex);
|
||||||
int videoDev = open(buffer, O_RDWR);
|
int videoDev = open(buffer, O_RDWR);
|
||||||
if (videoDev < 0)
|
|
||||||
LOG_ERROR_STR(buffer);
|
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
int result = 0;
|
uchar *result = NULL;
|
||||||
struct video_mbuf mbuf;
|
struct video_mbuf mbuf;
|
||||||
result |= ioctl(videoDev, VIDIOCGMBUF, &mbuf);
|
if (ioctl(videoDev, VIDIOCGMBUF, &mbuf) == 0) {
|
||||||
if (result == 0) {
|
|
||||||
int msize = mbuf.size;
|
int msize = mbuf.size;
|
||||||
unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
|
unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
|
||||||
if (mem && mem != (unsigned char *)-1) {
|
if (mem && mem != (unsigned char *)-1) {
|
||||||
// set up the size and RGB
|
// set up the size and RGB
|
||||||
struct video_capability vc;
|
struct video_capability vc;
|
||||||
result |= ioctl(videoDev, VIDIOCGCAP, &vc);
|
if (ioctl(videoDev, VIDIOCGCAP, &vc) == 0) {
|
||||||
struct video_mmap vm;
|
struct video_mmap vm;
|
||||||
vm.frame = 0;
|
vm.frame = 0;
|
||||||
if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
|
if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
|
||||||
(SizeY > 0) && (SizeY <= vc.maxheight)) {
|
(SizeY > 0) && (SizeY <= vc.maxheight)) {
|
||||||
vm.width = SizeX;
|
vm.width = SizeX;
|
||||||
vm.height = SizeY;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// write PNM file:
|
vm.width = vc.maxwidth;
|
||||||
if (fprintf(f, "P6\n%d\n%d\n255\n", vm.width, vm.height) < 0 ||
|
vm.height = vc.maxheight;
|
||||||
fwrite(mem, vm.width * vm.height * 3, 1, f) != 1) {
|
}
|
||||||
LOG_ERROR_STR(FileName);
|
vm.format = VIDEO_PALETTE_RGB24;
|
||||||
result |= 1;
|
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);
|
munmap(mem, msize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result |= 1;
|
esyslog("ERROR: failed to memmap video device");
|
||||||
}
|
}
|
||||||
close(videoDev);
|
close(videoDev);
|
||||||
return result == 0;
|
return result;
|
||||||
}
|
}
|
||||||
return false;
|
else
|
||||||
|
LOG_ERROR_STR(buffer);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDvbDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
|
void cDvbDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* 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.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
|
#ifndef __DVBDEVICE_H
|
||||||
@ -85,7 +85,7 @@ private:
|
|||||||
static int devVideoOffset;
|
static int devVideoOffset;
|
||||||
int devVideoIndex;
|
int devVideoIndex;
|
||||||
public:
|
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
|
// Video format facilities
|
||||||
|
|
||||||
|
4
svdrp.c
4
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* 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"
|
#include "svdrp.h"
|
||||||
@ -711,7 +711,7 @@ void cSVDRP::CmdGRAB(const char *Option)
|
|||||||
Reply(501, "Unexpected parameter \"%s\"", p);
|
Reply(501, "Unexpected parameter \"%s\"", p);
|
||||||
return;
|
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);
|
Reply(250, "Grabbed image %s", Option);
|
||||||
else
|
else
|
||||||
Reply(451, "Grab image failed");
|
Reply(451, "Grab image failed");
|
||||||
|
Loading…
Reference in New Issue
Block a user