1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Implemented overlay handling

This commit is contained in:
Klaus Schmidinger 2000-09-17 13:47:06 +02:00
parent b3c78919d5
commit 925780c20f
6 changed files with 310 additions and 5 deletions

View File

@ -20,6 +20,7 @@ Guido Fiala <gfiala@s.netic.de>
for implementing slow forward/back for implementing slow forward/back
for implementing the SVDRP command 'HITK' for implementing the SVDRP command 'HITK'
for implementing image grabbing for implementing image grabbing
for implementing overlay capabilities (see his 'kvdr' tool at http://www.s.netic.de/gfiala)
Robert Schneider <Robert.Schneider@lotus.com> Robert Schneider <Robert.Schneider@lotus.com>
for implementing EIT support for displaying the current/next info for implementing EIT support for displaying the current/next info

View File

@ -187,3 +187,6 @@ Video Disk Recorder Revision History
a parameter for a list of all valid key names. a parameter for a list of all valid key names.
- The new SVDRP command 'GRAB' (thanks to Guido Fiala!) can be used to grab - The new SVDRP command 'GRAB' (thanks to Guido Fiala!) can be used to grab
the current frame and save it to a file. the current frame and save it to a file.
- The new SVDRP commands 'OVL*' can be used to control video overlays (thanks
to Guido Fiala!). This is mainly for use in the 'kvdr' tool (see the 'kvdr'
page at http://www.s.netic.de/gfiala).

157
dvbapi.c
View File

@ -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: dvbapi.c 1.26 2000/09/17 11:53:35 kls Exp $ * $Id: dvbapi.c 1.27 2000/09/17 12:45:55 kls Exp $
*/ */
#include "dvbapi.h" #include "dvbapi.h"
@ -1069,6 +1069,11 @@ cDvbApi::cDvbApi(const char *FileName)
if (videoDev < 0) if (videoDev < 0)
LOG_ERROR; LOG_ERROR;
cols = rows = 0; cols = rows = 0;
ovlGeoSet = ovlStat = ovlFbSet = false;
ovlBrightness = ovlColour = ovlHue = ovlContrast = 32768;
ovlClipCount = 0;
#if defined(DEBUG_OSD) || defined(REMOTE_KBD) #if defined(DEBUG_OSD) || defined(REMOTE_KBD)
initscr(); initscr();
keypad(stdscr, true); keypad(stdscr, true);
@ -1093,6 +1098,7 @@ cDvbApi::~cDvbApi()
Close(); Close();
Stop(); Stop();
StopRecord(); StopRecord();
OvlO(false); //Overlay off!
close(videoDev); close(videoDev);
} }
#if defined(DEBUG_OSD) || defined(REMOTE_KBD) #if defined(DEBUG_OSD) || defined(REMOTE_KBD)
@ -1274,10 +1280,159 @@ bool cDvbApi::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX,
LOG_ERROR_STR(FileName); LOG_ERROR_STR(FileName);
result |= 1; result |= 1;
} }
if (ovlStat && ovlGeoSet) {
// switch the Overlay on again (gf: why have i to do anything again?)
OvlG(ovlSizeX, ovlSizeY, ovlPosX, ovlPosY);
}
if (ovlFbSet)
OvlP(ovlBrightness, ovlColour, ovlHue, ovlContrast);
munmap(mem, msize); munmap(mem, msize);
return result == 0; return result == 0;
} }
bool cDvbApi::OvlF(int SizeX, int SizeY, int FbAddr, int Bpp, int Palette)
{
int result = 0;
// get the actual X-Server settings???
// plausibility-check problem: can't be verified w/o X-server!!!
if (SizeX <= 0 || SizeY <= 0 || FbAddr == 0 || Bpp / 8 > 4 ||
Bpp / 8 <= 0 || Palette <= 0 || Palette > 13 || ovlClipCount < 0 ||
SizeX > 4096 || SizeY > 4096) {
ovlFbSet = ovlGeoSet = false;
OvlO(false);
return false;
}
else {
dsyslog(LOG_INFO, "OvlF: %d %d %x %d %d", SizeX, SizeY, FbAddr, Bpp, Palette);
// this is the problematic part!
struct video_buffer vb;
result |= ioctl(videoDev, VIDIOCGFBUF, &vb);
vb.base = (void*)FbAddr;
vb.depth = Bpp;
vb.height = SizeY;
vb.width = SizeX;
vb.bytesperline = ((vb.depth + 1) / 8) * vb.width;
//now the real thing: setting the framebuffer
result |= ioctl(videoDev, VIDIOCSFBUF, &vb);
if (result) {
ovlFbSet = ovlGeoSet = false;
ovlClipCount = 0;
OvlO(false);
return false;
}
else {
ovlFbSizeX = SizeX;
ovlFbSizeY = SizeY;
ovlBpp = Bpp;
ovlPalette = Palette;
ovlFbSet = true;
return true;
}
}
}
bool cDvbApi::OvlG(int SizeX, int SizeY, int PosX, int PosY)
{
int result = 0;
// get the actual X-Server settings???
struct video_capability vc;
result |= ioctl(videoDev, VIDIOCGCAP, &vc);
if (!ovlFbSet)
return false;
if (SizeX < vc.minwidth || SizeY < vc.minheight ||
SizeX > vc.maxwidth || SizeY>vc.maxheight
// || PosX > FbSizeX || PosY > FbSizeY
// PosX < -SizeX || PosY < -SizeY ||
) {
ovlGeoSet = false;
OvlO(false);
return false;
}
else {
struct video_window vw;
result |= ioctl(videoDev, VIDIOCGWIN, &vw);
vw.x = PosX;
vw.y = PosY;
vw.width = SizeX;
vw.height = SizeY;
vw.chromakey = ovlPalette;
vw.flags = VIDEO_WINDOW_CHROMAKEY; // VIDEO_WINDOW_INTERLACE; //VIDEO_CLIP_BITMAP;
vw.clips = ovlClipRects;
vw.clipcount = ovlClipCount;
result |= ioctl(videoDev, VIDIOCSWIN, &vw);
if (result) {
ovlGeoSet = false;
ovlClipCount = 0;
return false;
}
else {
ovlSizeX = SizeX;
ovlSizeY = SizeY;
ovlPosX = PosX;
ovlPosY = PosY;
ovlGeoSet = true;
ovlStat = true;
return true;
}
}
}
bool cDvbApi::OvlC(int ClipCount, CRect *cr)
{
if (ovlGeoSet && ovlFbSet) {
for (int i = 0; i < ClipCount; i++) {
ovlClipRects[i].x = cr[i].x;
ovlClipRects[i].y = cr[i].y;
ovlClipRects[i].width = cr[i].width;
ovlClipRects[i].height = cr[i].height;
ovlClipRects[i].next = &(ovlClipRects[i + 1]);
}
ovlClipCount = ClipCount;
//use it:
return OvlG(ovlSizeX, ovlSizeY, ovlPosX, ovlPosY);
}
return false;
}
bool cDvbApi::OvlP(__u16 Brightness, __u16 Colour, __u16 Hue, __u16 Contrast)
{
int result = 0;
ovlBrightness = Brightness;
ovlColour = Colour;
ovlHue = Hue;
ovlContrast = Contrast;
struct video_picture vp;
if (!ovlFbSet)
return false;
result |= ioctl(videoDev, VIDIOCGPICT, &vp);
vp.brightness = Brightness;
vp.colour = Colour;
vp.hue = Hue;
vp.contrast = Contrast;
vp.depth = ovlBpp;
vp.palette = ovlPalette; // gf: is this always ok? VIDEO_PALETTE_RGB565;
result |= ioctl(videoDev, VIDIOCSPICT, &vp);
return result == 0;
}
bool cDvbApi::OvlO(bool Value)
{
int result = 0;
if (!ovlGeoSet && Value)
return false;
int one = 1;
int zero = 0;
result |= ioctl(videoDev, VIDIOCCAPTURE, Value ? &one : &zero);
ovlStat = Value;
if (result) {
ovlStat = false;
return false;
}
return true;
}
#ifdef DEBUG_OSD #ifdef DEBUG_OSD
void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg) void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg)
{ {

View File

@ -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: dvbapi.h 1.15 2000/09/17 11:43:10 kls Exp $ * $Id: dvbapi.h 1.16 2000/09/17 12:15:05 kls Exp $
*/ */
#ifndef __DVBAPI_H #ifndef __DVBAPI_H
@ -21,6 +21,12 @@ typedef unsigned char __u8;
#include <stdio.h> #include <stdio.h>
#include <dvb.h> #include <dvb.h>
// Overlay facilities
#define MAXCLIPRECTS 100
typedef struct CRect {
signed short x, y, width, height;
};
#define MenuLines 15 #define MenuLines 15
#define MenuColumns 40 #define MenuColumns 40
@ -74,6 +80,21 @@ public:
bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1); bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
// Overlay facilities
private:
bool ovlStat, ovlGeoSet, ovlFbSet;
int ovlSizeX, ovlSizeY, ovlPosX, ovlPosY, ovlBpp, ovlPalette, ovlClips, ovlClipCount;
int ovlFbSizeX, ovlFbSizeY;
__u16 ovlBrightness, ovlColour, ovlHue, ovlContrast;
struct video_clip ovlClipRects[MAXCLIPRECTS];
public:
bool OvlF(int SizeX, int SizeY, int FbAddr, int Bpp, int Palette);
bool OvlG(int SizeX, int SizeY, int PosX, int PosY);
bool OvlC(int ClipCount, CRect *Cr);
bool OvlP(__u16 Brightness, __u16 Color, __u16 Hue, __u16 Contrast);
bool OvlO(bool Value);
// On Screen Display facilities // On Screen Display facilities
private: private:

122
svdrp.c
View File

@ -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.9 2000/09/17 11:29:33 kls Exp $ * $Id: svdrp.c 1.10 2000/09/17 13:39:37 kls Exp $
*/ */
#define _GNU_SOURCE #define _GNU_SOURCE
@ -154,6 +154,16 @@ const char *HelpPages[] = {
" Create a new timer. Settings must be in the same format as returned\n" " Create a new timer. Settings must be in the same format as returned\n"
" by the LSTT command. It is an error if a timer with the same channel,\n" " by the LSTT command. It is an error if a timer with the same channel,\n"
" day, start and stop time already exists.", " day, start and stop time already exists.",
"OVLF <sizex> <sizey> <fbaddr> <bpp> <palette>\n"
" Set the size, address depth and palette of the overlay.",
"OVLG <sizex> <sizey> <posx> <posy>\n"
" Set the size and position of the overlay.",
"OVLC <clipcount> <base16-CRect-array>\n"
" Set the overlay clipping rectangles.",
"OVLP <brightness> <colour> <hue> <contrast>\n"
" Set the picture parameters for the overlay.",
"OVLO 0 | 1\n"
" Switch the overlay on or off.",
"UPDT <settings>\n" "UPDT <settings>\n"
" Updates a timer. Settings must be in the same format as returned\n" " Updates a timer. Settings must be in the same format as returned\n"
" by the LSTT command. If a timer with the same channel, day, start\n" " by the LSTT command. If a timer with the same channel, day, start\n"
@ -240,8 +250,11 @@ bool cSVDRP::Send(const char *s, int length)
int wbytes = write(file, s, length); int wbytes = write(file, s, length);
if (wbytes == length) if (wbytes == length)
return true; return true;
if (wbytes < 0) if (wbytes < 0) {
LOG_ERROR; LOG_ERROR;
file.Close();
cDvbApi::PrimaryDvbApi->OvlO(false);
}
else //XXX while...??? else //XXX while...???
esyslog(LOG_ERR, "Wrote %d bytes to client while expecting %d\n", wbytes, length); esyslog(LOG_ERR, "Wrote %d bytes to client while expecting %d\n", wbytes, length);
return false; return false;
@ -659,6 +672,106 @@ void cSVDRP::CmdNEWT(const char *Option)
Reply(501, "Missing timer settings"); Reply(501, "Missing timer settings");
} }
void cSVDRP::CmdOVLF(const char *Option)
{
if (*Option) {
int SizeX = 0, SizeY = 0, Bpp = 0, Palette = 0, FbAddr = 0;
if (5 == sscanf(Option, "%d %d %x %d %d", &SizeX, &SizeY, &FbAddr, &Bpp, &Palette)) {
//somehow_set_overlay_geometry;
if (cDvbApi::PrimaryDvbApi->OvlF(SizeX, SizeY, FbAddr, Bpp, Palette))
Reply(250, "Overlay framebuffer set");
else
Reply(451, "Illegal overlay framebuffer settings");
}
else
Reply(501, "Could not parse overlay framebuffer settings");
}
else
Reply(501, "Missing overlay framebuffer settings");
}
void cSVDRP::CmdOVLG(const char *Option)
{
if (*Option) {
int SizeX = 0, SizeY = 0, PosX = 0, PosY = 0;
if (4 == sscanf(Option, "%d %d %d %d", &SizeX, &SizeY, &PosX, &PosY)) {
//somehow_set_overlay_geometry;
if (cDvbApi::PrimaryDvbApi->OvlG(SizeX, SizeY, PosX, PosY))
Reply(250, "Overlay geometry set");
else
Reply(451, "Illegal overlay geometry settings");
}
else
Reply(501, "Could not parse overlay geometry settings");
}
else
Reply(501, "Missing overlay geometry settings");
}
void cSVDRP::CmdOVLC(const char *Option)
{
if (*Option) {
int ClipCount = 0;
unsigned char s[2 * MAXCLIPRECTS * sizeof(CRect) + 2];
if (2 == sscanf(Option, "%d %s", &ClipCount, s)) {
// Base16-decoding of CRect-array:
unsigned char *p = (unsigned char*)ovlClipRects;
int i = 0, size = sizeof(CRect)*ClipCount;
for (int j = 0; i < size; i++) {
p[i] = (s[j++] - 65);
p[i] += (s[j++] - 65) << 4;
}
if (((unsigned)ClipCount == (i / sizeof(CRect))) && (ClipCount >= 0)) {
// apply it:
if (cDvbApi::PrimaryDvbApi->OvlC(ClipCount, ovlClipRects))
Reply(250, "Overlay-Clipping set");
else
Reply(451, "Illegal overlay clipping settings");
return;
}
}
Reply(501, "Error parsing Overlay-Clipping settings");
}
else
Reply(501, "Missing Clipping settings");
}
void cSVDRP::CmdOVLP(const char *Option)
{
if (*Option) {
int Brightness = 0, Colour = 0, Hue = 0, Contrast = 0;
if (4 == sscanf(Option, "%d %d %d %d", &Brightness, &Colour, &Hue, &Contrast)) {
//somehow_set_overlay_picture_settings;
if (cDvbApi::PrimaryDvbApi->OvlP(Brightness, Colour, Hue, Contrast))
Reply(250, "Overlay picture settings set");
else
Reply(451, "Illegal overlay picture settings");
}
else
Reply(501, "Could not parse overlay picture settings");
}
else
Reply(501, "Missing overlay picture settings");
}
void cSVDRP::CmdOVLO(const char *Option)
{
if (*Option) {
int Value;
if (1 == sscanf(Option, "%d", &Value)) {
//somehow_set_overlay_picture_settings;
if (cDvbApi::PrimaryDvbApi->OvlO(Value))
Reply(250, "Overlay capture set");
else
Reply(451, "Error setting overlay capture");
}
else
Reply(501, "Could not parse status");
}
else
Reply(501, "Missing overlay capture status");
}
void cSVDRP::CmdUPDT(const char *Option) void cSVDRP::CmdUPDT(const char *Option)
{ {
if (*Option) { if (*Option) {
@ -712,6 +825,11 @@ void cSVDRP::Execute(char *Cmd)
else if (CMD("MOVT")) CmdMOVT(s); else if (CMD("MOVT")) CmdMOVT(s);
else if (CMD("NEWC")) CmdNEWC(s); else if (CMD("NEWC")) CmdNEWC(s);
else if (CMD("NEWT")) CmdNEWT(s); else if (CMD("NEWT")) CmdNEWT(s);
else if (CMD("OVLF")) CmdOVLF(s);
else if (CMD("OVLG")) CmdOVLG(s);
else if (CMD("OVLC")) CmdOVLC(s);
else if (CMD("OVLP")) CmdOVLP(s);
else if (CMD("OVLO")) CmdOVLO(s);
else if (CMD("UPDT")) CmdUPDT(s); else if (CMD("UPDT")) CmdUPDT(s);
else if (CMD("QUIT") else if (CMD("QUIT")
|| CMD("\x04")) Close(); || CMD("\x04")) Close();

View File

@ -4,12 +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: svdrp.h 1.5 2000/09/17 10:22:49 kls Exp $ * $Id: svdrp.h 1.6 2000/09/17 13:22:04 kls Exp $
*/ */
#ifndef __SVDRP_H #ifndef __SVDRP_H
#define __SVDRP_H #define __SVDRP_H
#include "dvbapi.h"
#include "tools.h" #include "tools.h"
class cSocket { class cSocket {
@ -29,6 +30,7 @@ class cSVDRP {
private: private:
cSocket socket; cSocket socket;
cFile file; cFile file;
CRect ovlClipRects[MAXCLIPRECTS];
void Close(void); void Close(void);
bool Send(const char *s, int length = -1); bool Send(const char *s, int length = -1);
void Reply(int Code, const char *fmt, ...); void Reply(int Code, const char *fmt, ...);
@ -46,6 +48,11 @@ private:
void CmdMOVT(const char *Option); void CmdMOVT(const char *Option);
void CmdNEWC(const char *Option); void CmdNEWC(const char *Option);
void CmdNEWT(const char *Option); void CmdNEWT(const char *Option);
void CmdOVLF(const char *Option);
void CmdOVLG(const char *Option);
void CmdOVLC(const char *Option);
void CmdOVLP(const char *Option);
void CmdOVLO(const char *Option);
void CmdUPDT(const char *Option); void CmdUPDT(const char *Option);
void Execute(char *Cmd); void Execute(char *Cmd);
public: public: