mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
libtriple: implement working cVideo class
This commit is contained in:
545
libtriple/video_td.cpp
Normal file
545
libtriple/video_td.cpp
Normal file
@@ -0,0 +1,545 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* (C) 2002-2003 Andreas Oberritter <obi@tuxbox.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
//#include <zapit/zapit.h>
|
||||||
|
#include <zapit/debug.h>
|
||||||
|
//#include <zapit/settings.h>
|
||||||
|
|
||||||
|
#include <avs/avs_inf.h>
|
||||||
|
#include <clip/clipinfo.h>
|
||||||
|
#include "video_td.h"
|
||||||
|
#include <hardware/tddevices.h>
|
||||||
|
#define VIDEO_DEVICE "/dev/" DEVICE_NAME_VIDEO
|
||||||
|
|
||||||
|
cVideo * videoDecoder = NULL;
|
||||||
|
int system_rev = 0;
|
||||||
|
|
||||||
|
extern struct Ssettings settings;
|
||||||
|
|
||||||
|
cVideo::cVideo(int, void *, void *)
|
||||||
|
{
|
||||||
|
if ((fd = open(VIDEO_DEVICE, O_RDWR)) < 0)
|
||||||
|
ERROR(VIDEO_DEVICE);
|
||||||
|
|
||||||
|
playstate = VIDEO_STOPPED;
|
||||||
|
croppingMode = VID_DISPMODE_NORM;
|
||||||
|
outputformat = VID_OUTFMT_RGBC_SVIDEO;
|
||||||
|
scartvoltage = -1;
|
||||||
|
z[0] = 100;
|
||||||
|
z[1] = 100;
|
||||||
|
zoomvalue = &z[0];
|
||||||
|
const char *blanknames[2] = { "/share/tuxbox/blank_576.mpg", "/share/tuxbox/blank_480.mpg" };
|
||||||
|
int blankfd;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
blank_data[i] = NULL; /* initialize */
|
||||||
|
blank_size[i] = 0;
|
||||||
|
blankfd = open(blanknames[i], O_RDONLY);
|
||||||
|
if (blankfd < 0)
|
||||||
|
{
|
||||||
|
WARN("cannot open %s: %m", blanknames[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fstat(blankfd, &st) != -1 && st.st_size > 0)
|
||||||
|
{
|
||||||
|
blank_size[i] = st.st_size;
|
||||||
|
blank_data[i] = malloc(blank_size[i]);
|
||||||
|
if (! blank_data[i])
|
||||||
|
ERROR("cannot malloc memory");
|
||||||
|
else if (read(blankfd, blank_data[i], blank_size[i]) != blank_size[i])
|
||||||
|
{
|
||||||
|
ERROR("short read");
|
||||||
|
free(blank_data[i]); /* don't leak... */
|
||||||
|
blank_data[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(blankfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cVideo::~cVideo(void)
|
||||||
|
{
|
||||||
|
playstate = VIDEO_STOPPED;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (blank_data[i])
|
||||||
|
free(blank_data[i]);
|
||||||
|
blank_data[i] = NULL;
|
||||||
|
}
|
||||||
|
/* disable DACs and SCART voltage */
|
||||||
|
Standby(true);
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::setAspectRatio(int aspect, int mode)
|
||||||
|
{
|
||||||
|
static int _mode = -1;
|
||||||
|
static int _aspect = -1;
|
||||||
|
vidDispSize_t dsize = VID_DISPSIZE_UNKNOWN;
|
||||||
|
vidDispMode_t dmode = VID_DISPMODE_NORM;
|
||||||
|
/* 1 = 4:3, 3 = 16:9, 4 = 2.21:1, 0 = unknown */
|
||||||
|
int v_ar = getAspectRatio();
|
||||||
|
|
||||||
|
if (aspect != -1)
|
||||||
|
_aspect = aspect;
|
||||||
|
if (mode != -1)
|
||||||
|
_mode = mode;
|
||||||
|
fprintf(stderr, "cVideo::setAspectRatio(%d, %d)_(%d, %d) v_ar %d\n", aspect, mode, _aspect, _mode, v_ar);
|
||||||
|
|
||||||
|
/* values are hardcoded in neutrino_menue.cpp, "2" is 14:9 -> not used */
|
||||||
|
if (_aspect != -1)
|
||||||
|
{
|
||||||
|
switch(_aspect)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
dsize = VID_DISPSIZE_4x3;
|
||||||
|
scartvoltage = 12;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
dsize = VID_DISPSIZE_16x9;
|
||||||
|
scartvoltage = 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_mode != -1)
|
||||||
|
{
|
||||||
|
switch(_mode)
|
||||||
|
{
|
||||||
|
case DISPLAY_AR_MODE_PANSCAN:
|
||||||
|
if (v_ar < 3)
|
||||||
|
dsize = VID_DISPSIZE_4x3;
|
||||||
|
break;
|
||||||
|
case DISPLAY_AR_MODE_LETTERBOX:
|
||||||
|
dmode = VID_DISPMODE_LETTERBOX;
|
||||||
|
break;
|
||||||
|
case DISPLAY_AR_MODE_PANSCAN2:
|
||||||
|
if ((v_ar < 3 && _aspect == 3) || (v_ar >= 3 && _aspect == 1))
|
||||||
|
{
|
||||||
|
/* unfortunately, this partly reimplements the setZoom code... */
|
||||||
|
int zoom = 100 * 16 / 14; /* 16:9 vs 14:9 */
|
||||||
|
dsize = VID_DISPSIZE_UNKNOWN;
|
||||||
|
dmode = VID_DISPMODE_SCALE;
|
||||||
|
SCALEINFO s;
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
if (v_ar < 3) { /* 4:3 */
|
||||||
|
s.src.hori_size = 720;
|
||||||
|
s.src.vert_size = 2 * 576 - 576 * zoom / 100;
|
||||||
|
s.des.hori_size = zoom * 720 * 3/4 / 100;
|
||||||
|
s.des.vert_size = 576;
|
||||||
|
} else {
|
||||||
|
s.src.hori_size = 2 * 720 - 720 * zoom / 100;
|
||||||
|
s.src.vert_size = 576;
|
||||||
|
s.des.hori_size = 720;
|
||||||
|
s.des.vert_size = zoom * 576 * 3/4 / 100;
|
||||||
|
}
|
||||||
|
s.des.vert_off = (576 - s.des.vert_size) / 2;
|
||||||
|
s.des.hori_off = (720 - s.des.hori_size) / 2;
|
||||||
|
lt_debug("PANSCAN2: %d%% src: %d:%d:%d:%d dst: %d:%d:%d:%d\n", zoom,
|
||||||
|
s.src.hori_off,s.src.vert_off,s.src.hori_size,s.src.vert_size,
|
||||||
|
s.des.hori_off,s.des.vert_off,s.des.hori_size,s.des.vert_size);
|
||||||
|
fop(ioctl, MPEG_VID_SCALE_ON);
|
||||||
|
fop(ioctl, MPEG_VID_SET_SCALE_POS, &s);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setCroppingMode(dmode);
|
||||||
|
}
|
||||||
|
const char *ds[] = { "4x3", "16x9", "2.21", "unknown" };
|
||||||
|
const char *d;
|
||||||
|
if (dsize >=0 && dsize < 4)
|
||||||
|
d = ds[dsize];
|
||||||
|
else
|
||||||
|
d = "invalid!";
|
||||||
|
lt_debug("cVideo::setAspectRatio:dispsize(%d) (%s)\n", dsize, d);
|
||||||
|
fop(ioctl, MPEG_VID_SET_DISPSIZE, dsize);
|
||||||
|
|
||||||
|
int avsfd = open("/dev/stb/tdsystem", O_RDONLY);
|
||||||
|
if (avsfd < 0)
|
||||||
|
{
|
||||||
|
perror("open tdsystem");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lt_debug("cVideo::setAspectRatio: setting SCART_PIN_8 to %dV\n", scartvoltage);
|
||||||
|
if (scartvoltage > 0 && ioctl(avsfd, IOC_AVS_SCART_PIN8_SET, scartvoltage) < 0)
|
||||||
|
perror("IOC_AVS_SCART_PIN8_SET");
|
||||||
|
close(avsfd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::getAspectRatio(void)
|
||||||
|
{
|
||||||
|
VIDEOINFO v;
|
||||||
|
/* this memset silences *TONS* of valgrind warnings */
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
quiet_fop(ioctl, MPEG_VID_GET_V_INFO, &v);
|
||||||
|
if (v.pel_aspect_ratio < VID_DISPSIZE_4x3 || v.pel_aspect_ratio > VID_DISPSIZE_UNKNOWN)
|
||||||
|
{
|
||||||
|
WARN("invalid value %d, returning 0 for 'unknown' fd: %d", v.pel_aspect_ratio, fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* convert to Coolstream api values. Taken from streaminfo2.cpp */
|
||||||
|
switch (v.pel_aspect_ratio)
|
||||||
|
{
|
||||||
|
case VID_DISPSIZE_4x3:
|
||||||
|
return 1;
|
||||||
|
case VID_DISPSIZE_16x9:
|
||||||
|
return 3;
|
||||||
|
case VID_DISPSIZE_221x100:
|
||||||
|
return 4;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::setCroppingMode(vidDispMode_t format)
|
||||||
|
{
|
||||||
|
croppingMode = format;
|
||||||
|
const char *format_string[] = { "norm", "letterbox", "unknown", "mode_1_2", "mode_1_4", "mode_2x", "scale", "disexp" };
|
||||||
|
const char *f;
|
||||||
|
if (format >= VID_DISPMODE_NORM && format <= VID_DISPMODE_DISEXP)
|
||||||
|
f = format_string[format];
|
||||||
|
else
|
||||||
|
f = "ILLEGAL format!";
|
||||||
|
lt_debug("cVideo::setCroppingMode(%d) => %s\n", format, f);
|
||||||
|
return fop(ioctl, MPEG_VID_SET_DISPMODE, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::Start(void * /*PcrChannel*/, unsigned short /*PcrPid*/, unsigned short /*VideoPid*/, void * /*hChannel*/)
|
||||||
|
{
|
||||||
|
if (playstate == VIDEO_PLAYING)
|
||||||
|
return 0;
|
||||||
|
if (playstate == VIDEO_FREEZED) /* in theory better, but not in practice :-) */
|
||||||
|
fop(ioctl, MPEG_VID_CONTINUE);
|
||||||
|
playstate = VIDEO_PLAYING;
|
||||||
|
fop(ioctl, MPEG_VID_PLAY);
|
||||||
|
return fop(ioctl, MPEG_VID_SYNC_ON, VID_SYNC_AUD);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::Stop(bool blank)
|
||||||
|
{
|
||||||
|
//fprintf(stderr, "cVideo::Stop %d\n", blank);
|
||||||
|
if (blank)
|
||||||
|
{
|
||||||
|
playstate = VIDEO_STOPPED;
|
||||||
|
fop(ioctl, MPEG_VID_STOP);
|
||||||
|
return setBlank(1);
|
||||||
|
}
|
||||||
|
playstate = VIDEO_FREEZED;
|
||||||
|
return fop(ioctl, MPEG_VID_FREEZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::setBlank(int)
|
||||||
|
{
|
||||||
|
/* The TripleDragon has no VIDEO_SET_BLANK ioctl.
|
||||||
|
instead, you write a black still-MPEG Iframe into the decoder.
|
||||||
|
The original software uses different files for 4:3 and 16:9 and
|
||||||
|
for PAL and NTSC. I optimized that a little bit
|
||||||
|
*/
|
||||||
|
int index = 0; /* default PAL */
|
||||||
|
VIDEOINFO v;
|
||||||
|
BUFINFO buf;
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
quiet_fop(ioctl, MPEG_VID_GET_V_INFO, &v);
|
||||||
|
|
||||||
|
if ((v.v_size % 240) == 0) /* NTSC */
|
||||||
|
{
|
||||||
|
INFO("NTSC format detected");
|
||||||
|
index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blank_data[index] == NULL) /* no MPEG found */
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* hack: this might work only on those two still-MPEG files!
|
||||||
|
I diff'ed the 4:3 and the 16:9 still mpeg from the original
|
||||||
|
soft and spotted the single bit difference, so there is no
|
||||||
|
need to keep two different MPEGs in memory
|
||||||
|
If we would read them from disk all the time it would be
|
||||||
|
slower and it might wake up the drive occasionally */
|
||||||
|
if (v.pel_aspect_ratio == VID_DISPSIZE_4x3)
|
||||||
|
((char *)blank_data[index])[7] &= ~0x10; // clear the bit
|
||||||
|
else
|
||||||
|
((char *)blank_data[index])[7] |= 0x10; // set the bit
|
||||||
|
|
||||||
|
//WARN("blank[7] == 0x%02x", ((char *)blank_data[index])[7]);
|
||||||
|
|
||||||
|
buf.ulLen = blank_size[index];
|
||||||
|
buf.ulStartAdrOff = (int)blank_data[index];
|
||||||
|
fop(ioctl, MPEG_VID_STILLP_WRITE, &buf);
|
||||||
|
return fop(ioctl, MPEG_VID_SELECT_SOURCE, VID_SOURCE_DEMUX);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::SetVideoSystem(int video_system, bool remember)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "cVideo::setVideoSystem(%d, %d)\n", video_system, remember);
|
||||||
|
if (video_system > VID_DISPFMT_SECAM || video_system < 0)
|
||||||
|
video_system = VID_DISPFMT_PAL;
|
||||||
|
return fop(ioctl, MPEG_VID_SET_DISPFMT, video_system);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::getPlayState(void)
|
||||||
|
{
|
||||||
|
return playstate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::SetVideoMode(analog_mode_t mode)
|
||||||
|
{
|
||||||
|
lt_debug("cVideo::setVideoMode(%d)\n", mode);
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case ANALOG_SD_YPRPB_SCART:
|
||||||
|
outputformat = VID_OUTFMT_YBR_SVIDEO;
|
||||||
|
break;
|
||||||
|
case ANALOG_SD_RGB_SCART:
|
||||||
|
outputformat = VID_OUTFMT_RGBC_SVIDEO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "cVideo::setVideoMode: unknown mode %d\n", mode);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fop(ioctl, MPEG_VID_SET_OUTFMT, outputformat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::ShowPicture(const char * fname)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "cVideo::ShowPicture: %s\n", fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::StopPicture()
|
||||||
|
{
|
||||||
|
lt_debug("cVideo::StopPicture()\n");
|
||||||
|
fop(ioctl, MPEG_VID_SELECT_SOURCE, VID_SOURCE_DEMUX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::Standby(unsigned int bOn)
|
||||||
|
{
|
||||||
|
lt_debug("cVideo::Standby: %d\n", bOn);
|
||||||
|
if (bOn)
|
||||||
|
{
|
||||||
|
setBlank(1);
|
||||||
|
fop(ioctl, MPEG_VID_SET_OUTFMT, VID_OUTFMT_DISABLE_DACS);
|
||||||
|
} else
|
||||||
|
fop(ioctl, MPEG_VID_SET_OUTFMT, outputformat);
|
||||||
|
routeVideo(bOn);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cVideo::getBlank(void)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "cVideo::getBlank\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set zoom in percent (100% == 1:1) */
|
||||||
|
int cVideo::setZoom(int zoom)
|
||||||
|
{
|
||||||
|
if (zoom == -1) // "auto" reset
|
||||||
|
zoom = *zoomvalue;
|
||||||
|
|
||||||
|
if (zoom > 150 || zoom < 100)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*zoomvalue = zoom;
|
||||||
|
|
||||||
|
if (zoom == 100)
|
||||||
|
{
|
||||||
|
setCroppingMode(croppingMode);
|
||||||
|
return fop(ioctl, MPEG_VID_SCALE_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the SCALEINFO describes the source and destination of the scaled
|
||||||
|
video. "src" is the part of the source picture that gets scaled,
|
||||||
|
"dst" is the area on the screen where this part is displayed
|
||||||
|
Messing around with MPEG_VID_SET_SCALE_POS disables the automatic
|
||||||
|
letterboxing, which, as I guess, is only a special case of
|
||||||
|
MPEG_VID_SET_SCALE_POS. Therefor we need to care for letterboxing
|
||||||
|
etc here, which is probably not yet totally correct */
|
||||||
|
SCALEINFO s;
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
if (zoom > 100)
|
||||||
|
{
|
||||||
|
vidDispSize_t x = (vidDispSize_t)getAspectRatio();
|
||||||
|
if (x == VID_DISPSIZE_4x3 && croppingMode == VID_DISPMODE_NORM)
|
||||||
|
{
|
||||||
|
s.src.hori_size = 720;
|
||||||
|
s.des.hori_size = 720 * 3/4 * zoom / 100;
|
||||||
|
if (s.des.hori_size > 720)
|
||||||
|
{
|
||||||
|
/* the destination exceeds the screen size.
|
||||||
|
TODO: decrease source size to allow higher
|
||||||
|
zoom factors (is this useful ?) */
|
||||||
|
s.des.hori_size = 720;
|
||||||
|
zoom = 133; // (720*4*100)/(720*3)
|
||||||
|
*zoomvalue = zoom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.src.hori_size = 2 * 720 - 720 * zoom / 100;
|
||||||
|
s.des.hori_size = 720;
|
||||||
|
}
|
||||||
|
s.src.vert_size = 2 * 576 - 576 * zoom / 100;
|
||||||
|
s.des.hori_off = (720 - s.des.hori_size) / 2;
|
||||||
|
s.des.vert_size = 576;
|
||||||
|
}
|
||||||
|
/* not working correctly (wrong formula) and does not make sense IMHO
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.src.hori_size = 720;
|
||||||
|
s.src.vert_size = 576;
|
||||||
|
s.des.hori_size = 720 * zoom / 100;
|
||||||
|
s.des.vert_size = 576 * zoom / 100;
|
||||||
|
s.des.hori_off = (720 - s.des.hori_size) / 2;
|
||||||
|
s.des.vert_off = (576 - s.des.vert_size) / 2;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
DBG("setZoom: %d%% src: %d:%d:%d:%d dst: %d:%d:%d:%d", zoom,
|
||||||
|
s.src.hori_off,s.src.vert_off,s.src.hori_size,s.src.vert_size,
|
||||||
|
s.des.hori_off,s.des.vert_off,s.des.hori_size,s.des.vert_size);
|
||||||
|
fop(ioctl, MPEG_VID_SET_DISPMODE, VID_DISPMODE_SCALE);
|
||||||
|
fop(ioctl, MPEG_VID_SCALE_ON);
|
||||||
|
return fop(ioctl, MPEG_VID_SET_SCALE_POS, &s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int cVideo::getZoom(void)
|
||||||
|
{
|
||||||
|
return *zoomvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::setZoomAspect(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > 1)
|
||||||
|
WARN("index out of range");
|
||||||
|
else
|
||||||
|
zoomvalue = &z[index];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void cVideo::Pig(int x, int y, int w, int h, int /*osd_w*/, int /*osd_h*/)
|
||||||
|
{
|
||||||
|
/* x = y = w = h = -1 -> reset / "hide" PIG */
|
||||||
|
if (x == -1 && y == -1 && w == -1 && h == -1)
|
||||||
|
{
|
||||||
|
setZoom(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SCALEINFO s;
|
||||||
|
memset(&s, 0, sizeof(s));
|
||||||
|
s.src.hori_size = 720;
|
||||||
|
s.src.vert_size = 576;
|
||||||
|
s.des.hori_off = x;
|
||||||
|
s.des.vert_off = y;
|
||||||
|
s.des.hori_size = w;
|
||||||
|
s.des.vert_size = h;
|
||||||
|
DBG("setPig src: %d:%d:%d:%d dst: %d:%d:%d:%d",
|
||||||
|
s.src.hori_off,s.src.vert_off,s.src.hori_size,s.src.vert_size,
|
||||||
|
s.des.hori_off,s.des.vert_off,s.des.hori_size,s.des.vert_size);
|
||||||
|
fop(ioctl, MPEG_VID_SET_DISPMODE, VID_DISPMODE_SCALE);
|
||||||
|
fop(ioctl, MPEG_VID_SCALE_ON);
|
||||||
|
fop(ioctl, MPEG_VID_SET_SCALE_POS, &s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::getPictureInfo(int &width, int &height, int &rate)
|
||||||
|
{
|
||||||
|
VIDEOINFO v;
|
||||||
|
/* this memset silences *TONS* of valgrind warnings */
|
||||||
|
memset(&v, 0, sizeof(v));
|
||||||
|
quiet_fop(ioctl, MPEG_VID_GET_V_INFO, &v);
|
||||||
|
/* convert to Coolstream API */
|
||||||
|
rate = (int)v.frame_rate - 1;
|
||||||
|
width = (int)v.h_size;
|
||||||
|
height = (int)v.v_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::SetSyncMode(AVSYNC_TYPE /*Mode*/)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "cVideo::%s\n", __FUNCTION__);
|
||||||
|
};
|
||||||
|
|
||||||
|
int cVideo::SetStreamType(VIDEO_FORMAT type)
|
||||||
|
{
|
||||||
|
static const char *VF[] = {
|
||||||
|
"VIDEO_FORMAT_MPEG2",
|
||||||
|
"VIDEO_FORMAT_MPEG4",
|
||||||
|
"VIDEO_FORMAT_VC1",
|
||||||
|
"VIDEO_FORMAT_JPEG",
|
||||||
|
"VIDEO_FORMAT_GIF",
|
||||||
|
"VIDEO_FORMAT_PNG"
|
||||||
|
};
|
||||||
|
|
||||||
|
lt_debug("cVideo::SetStreamType - type=%s\n", VF[type]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cVideo::routeVideo(int standby)
|
||||||
|
{
|
||||||
|
lt_debug("cVideo::routeVideo(%d)\n", standby);
|
||||||
|
|
||||||
|
int avsfd = open("/dev/stb/tdsystem", O_RDONLY);
|
||||||
|
if (avsfd < 0)
|
||||||
|
{
|
||||||
|
perror("open tdsystem");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* in standby, we always route VCR scart to the TV. Once there is a UI
|
||||||
|
to configure this, we can think more about this... */
|
||||||
|
if (standby)
|
||||||
|
{
|
||||||
|
printf("[routeVideo] setting FASTBLANK to follow VCR SCART\n");
|
||||||
|
if (ioctl(avsfd, IOC_AVS_FASTBLANK_SET, (unsigned char)3) < 0)
|
||||||
|
perror("IOC_AVS_FASTBLANK_SET, 3");
|
||||||
|
/* TODO: should probably depend on aspect ratio setting */
|
||||||
|
printf("[routeVideo] setting SCART_PIN_8 to follow VCR SCART\n");
|
||||||
|
if (ioctl(avsfd, IOC_AVS_SCART_PIN8_FOLLOW_VCR) < 0)
|
||||||
|
perror("IOC_AVS_SCART_PIN8_FOLLOW_VCR");
|
||||||
|
printf("[routeVideo] routing VCR to TV SCART\n");
|
||||||
|
if (ioctl(avsfd, IOC_AVS_ROUTE_VCR2TV) < 0)
|
||||||
|
perror("IOC_AVS_ROUTE_VCR2TV");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned char fblk = 1;
|
||||||
|
printf("[routeVideo] setting FASTBLANK to %d\n", fblk);
|
||||||
|
if (ioctl(avsfd, IOC_AVS_FASTBLANK_SET, fblk) < 0)
|
||||||
|
perror("IOC_AVS_FASTBLANK_SET, fblk");
|
||||||
|
printf("[routeVideo] setting SCART_PIN_8 to %dV\n", scartvoltage);
|
||||||
|
if (ioctl(avsfd, IOC_AVS_SCART_PIN8_SET, scartvoltage) < 0)
|
||||||
|
perror("IOC_AVS_SCART_PIN8_SET");
|
||||||
|
printf("[routeVideo] routing TV encoder to TV SCART\n");
|
||||||
|
if (ioctl(avsfd, IOC_AVS_ROUTE_ENC2TV) < 0)
|
||||||
|
perror("IOC_AVS_ROUTE_ENC2TV");
|
||||||
|
close(avsfd);
|
||||||
|
}
|
189
libtriple/video_td.h
Normal file
189
libtriple/video_td.h
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
#ifndef _VIDEO_TD_H
|
||||||
|
#define _VIDEO_TD_H
|
||||||
|
|
||||||
|
#include <hardware/vid/vid_inf.h>
|
||||||
|
#define video_format_t vidDispSize_t
|
||||||
|
//#define video_displayformat_t vidDispMode_t
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ANALOG_SD_RGB_SCART = 0x00,
|
||||||
|
ANALOG_SD_YPRPB_SCART,
|
||||||
|
ANALOG_HD_RGB_SCART,
|
||||||
|
ANALOG_HD_YPRPB_SCART,
|
||||||
|
ANALOG_SD_RGB_CINCH = 0x80,
|
||||||
|
ANALOG_SD_YPRPB_CINCH,
|
||||||
|
ANALOG_HD_RGB_CINCH,
|
||||||
|
ANALOG_HD_YPRPB_CINCH,
|
||||||
|
} analog_mode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_FORMAT_MPEG2 = 0,
|
||||||
|
VIDEO_FORMAT_MPEG4,
|
||||||
|
VIDEO_FORMAT_VC1,
|
||||||
|
VIDEO_FORMAT_JPEG,
|
||||||
|
VIDEO_FORMAT_GIF,
|
||||||
|
VIDEO_FORMAT_PNG
|
||||||
|
} VIDEO_FORMAT;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_SD = 0,
|
||||||
|
VIDEO_HD,
|
||||||
|
VIDEO_120x60i,
|
||||||
|
VIDEO_320x240i,
|
||||||
|
VIDEO_1440x800i,
|
||||||
|
VIDEO_360x288i
|
||||||
|
} VIDEO_DEFINITION;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_FRAME_RATE_23_976 = 0,
|
||||||
|
VIDEO_FRAME_RATE_24,
|
||||||
|
VIDEO_FRAME_RATE_25,
|
||||||
|
VIDEO_FRAME_RATE_29_97,
|
||||||
|
VIDEO_FRAME_RATE_30,
|
||||||
|
VIDEO_FRAME_RATE_50,
|
||||||
|
VIDEO_FRAME_RATE_59_94,
|
||||||
|
VIDEO_FRAME_RATE_60
|
||||||
|
} VIDEO_FRAME_RATE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DISPLAY_AR_1_1,
|
||||||
|
DISPLAY_AR_4_3,
|
||||||
|
DISPLAY_AR_14_9,
|
||||||
|
DISPLAY_AR_16_9,
|
||||||
|
DISPLAY_AR_20_9,
|
||||||
|
DISPLAY_AR_RAW,
|
||||||
|
} DISPLAY_AR;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DISPLAY_AR_MODE_PANSCAN = 0,
|
||||||
|
DISPLAY_AR_MODE_LETTERBOX,
|
||||||
|
DISPLAY_AR_MODE_NONE,
|
||||||
|
DISPLAY_AR_MODE_PANSCAN2
|
||||||
|
} DISPLAY_AR_MODE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_DB_DR_NEITHER = 0,
|
||||||
|
VIDEO_DB_ON,
|
||||||
|
VIDEO_DB_DR_BOTH
|
||||||
|
} VIDEO_DB_DR;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_PLAY_STILL = 0,
|
||||||
|
VIDEO_PLAY_CLIP,
|
||||||
|
VIDEO_PLAY_TRICK,
|
||||||
|
VIDEO_PLAY_MOTION,
|
||||||
|
VIDEO_PLAY_MOTION_NO_SYNC
|
||||||
|
} VIDEO_PLAY_MODE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_STD_NTSC = VID_DISPFMT_NTSC, /* 0 */
|
||||||
|
VIDEO_STD_PAL = VID_DISPFMT_PAL, /* 1 */
|
||||||
|
VIDEO_STD_SECAM = VID_DISPFMT_SECAM, /* 4 */
|
||||||
|
VIDEO_STD_1080I50 = VIDEO_STD_PAL, /* hack, this is used in neutrino settings default */
|
||||||
|
VIDEO_STD_MAX = VIDEO_STD_SECAM
|
||||||
|
} VIDEO_STD;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_STOPPED, /* Video is stopped */
|
||||||
|
VIDEO_PLAYING, /* Video is currently playing */
|
||||||
|
VIDEO_FREEZED /* Video is freezed */
|
||||||
|
} video_play_state_t;
|
||||||
|
|
||||||
|
/* not used, for dummy functions */
|
||||||
|
typedef enum {
|
||||||
|
VIDEO_HDMI_CEC_MODE_OFF = 0,
|
||||||
|
VIDEO_HDMI_CEC_MODE_TUNER,
|
||||||
|
VIDEO_HDMI_CEC_MODE_RECORDER
|
||||||
|
} VIDEO_HDMI_CEC_MODE;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VIDEO_CONTROL_BRIGHTNESS = 0,
|
||||||
|
VIDEO_CONTROL_CONTRAST,
|
||||||
|
VIDEO_CONTROL_SATURATION,
|
||||||
|
VIDEO_CONTROL_HUE,
|
||||||
|
VIDEO_CONTROL_SHARPNESS,
|
||||||
|
VIDEO_CONTROL_MAX = VIDEO_CONTROL_SHARPNESS
|
||||||
|
} VIDEO_CONTROL;
|
||||||
|
|
||||||
|
|
||||||
|
class cVideo
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/* video device */
|
||||||
|
int fd;
|
||||||
|
/* apparently we cannot query the driver's state
|
||||||
|
=> remember it */
|
||||||
|
video_play_state_t playstate;
|
||||||
|
vidDispMode_t croppingMode;
|
||||||
|
vidOutFmt_t outputformat;
|
||||||
|
int scartvoltage;
|
||||||
|
int z[2]; /* zoomvalue for 4:3 (0) and 16:9 (1) in percent */
|
||||||
|
int *zoomvalue;
|
||||||
|
void *blank_data[2]; /* we store two blank MPEGs (PAL/NTSC) in there */
|
||||||
|
int blank_size[2];
|
||||||
|
|
||||||
|
VIDEO_FORMAT StreamType;
|
||||||
|
VIDEO_DEFINITION VideoDefinition;
|
||||||
|
DISPLAY_AR DisplayAR;
|
||||||
|
VIDEO_PLAY_MODE SyncMode;
|
||||||
|
DISPLAY_AR_MODE ARMode;
|
||||||
|
VIDEO_DB_DR eDbDr;
|
||||||
|
DISPLAY_AR PictureAR;
|
||||||
|
VIDEO_FRAME_RATE FrameRate;
|
||||||
|
void routeVideo(int standby);
|
||||||
|
public:
|
||||||
|
/* constructor & destructor */
|
||||||
|
cVideo(int mode, void *, void *);
|
||||||
|
~cVideo(void);
|
||||||
|
|
||||||
|
void * GetTVEnc() { return NULL; };
|
||||||
|
void * GetTVEncSD() { return NULL; };
|
||||||
|
|
||||||
|
/* aspect ratio */
|
||||||
|
int getAspectRatio(void);
|
||||||
|
void getPictureInfo(int &width, int &height, int &rate);
|
||||||
|
int setAspectRatio(int aspect, int mode);
|
||||||
|
|
||||||
|
/* cropping mode */
|
||||||
|
int setCroppingMode(vidDispMode_t x = VID_DISPMODE_NORM);
|
||||||
|
|
||||||
|
/* get play state */
|
||||||
|
int getPlayState(void);
|
||||||
|
|
||||||
|
/* blank on freeze */
|
||||||
|
int getBlank(void);
|
||||||
|
int setBlank(int enable);
|
||||||
|
|
||||||
|
/* change video play state. Parameters are all unused. */
|
||||||
|
int Start(void *PcrChannel = NULL, unsigned short PcrPid = 0, unsigned short VideoPid = 0, void *x = NULL);
|
||||||
|
int Stop(bool blank = true);
|
||||||
|
bool Pause(void);
|
||||||
|
|
||||||
|
/* set video_system */
|
||||||
|
int SetVideoSystem(int video_system, bool remember = true);
|
||||||
|
int SetStreamType(VIDEO_FORMAT type);
|
||||||
|
#define AVSYNC_TYPE int
|
||||||
|
void SetSyncMode(AVSYNC_TYPE mode);
|
||||||
|
bool SetCECMode(VIDEO_HDMI_CEC_MODE) { return true; };
|
||||||
|
void SetCECAutoView(bool) { return; };
|
||||||
|
void SetCECAutoStandby(bool) { return; };
|
||||||
|
void ShowPicture(const char * fname);
|
||||||
|
void StopPicture();
|
||||||
|
void Standby(unsigned int bOn);
|
||||||
|
void Pig(int x, int y, int w, int h, int osd_w = 1064, int osd_h = 600);
|
||||||
|
void SetControl(int, int) { return; };
|
||||||
|
int setZoom(int);
|
||||||
|
void setContrast(int val);
|
||||||
|
void SetVideoMode(analog_mode_t mode);
|
||||||
|
void SetDBDR(int) { return; };
|
||||||
|
void SetAudioHandle(void *) { return; };
|
||||||
|
void SetAutoModes(int [VIDEO_STD_MAX]) { return; };
|
||||||
|
int OpenVBI(int) { return 0; };
|
||||||
|
int CloseVBI(void) { return 0; };
|
||||||
|
int StartVBI(unsigned short) { return 0; };
|
||||||
|
int StopVBI(void) { return 0; };
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user