summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--dxr3.c19
-rw-r--r--dxr3.h1
-rw-r--r--dxr3audio-oss.c7
-rw-r--r--dxr3device.c332
-rw-r--r--dxr3device.h46
-rw-r--r--dxr3interface.c595
-rw-r--r--dxr3interface.h161
-rw-r--r--dxr3osd.c4
-rw-r--r--dxr3spudecoder.c1
-rw-r--r--spuencoder.c8
11 files changed, 332 insertions, 845 deletions
diff --git a/Makefile b/Makefile
index c05f4b6..a324c89 100644
--- a/Makefile
+++ b/Makefile
@@ -69,8 +69,7 @@ DEFINES += -DMICROCODE=\"/lib/firmware/em8300.bin\"
OBJS = $(PLUGIN).o dxr3multichannelaudio.o \
dxr3audiodecoder.o dxr3blackframe.o dxr3audio.o \
dxr3pesframe.o settings.o \
- dxr3interface.o dxr3device.o \
- dxr3osd.o dxr3spudecoder.o \
+ dxr3device.o dxr3osd.o dxr3spudecoder.o \
dxr3audio-oss.o dxr3audio-alsa.o spuencoder.o spuregion.o scaler.o
### Default target:
diff --git a/dxr3.c b/dxr3.c
index f43bf36..b584940 100644
--- a/dxr3.c
+++ b/dxr3.c
@@ -29,7 +29,7 @@ eOSState cDxr3OsdItem::ProcessKey(eKeys Key)
switch (m_item)
{
case DXR3_RESET_HARDWARE:
- cDxr3Interface::instance()->ResetHardware();
+ //cDxr3Interface::instance()->ResetHardware();
//cDxr3Device::Instance().Reset();
break;
@@ -109,7 +109,7 @@ void cMenuSetupDxr3::Store(void)
// Apply (some of the) settings
- cDxr3Interface::instance()->updateBcsValues();
+ //cDxr3Interface::instance()->updateBcsValues();
//cDxr3Device::instance()->Reset();
}
@@ -136,9 +136,6 @@ public:
cMenuSetupPage *SetupMenu();
bool SetupParse(const char *Name, const char *Value);
-
-private:
- cDxr3Device *device;
};
// ==================================
@@ -158,7 +155,7 @@ cPluginDxr3::~cPluginDxr3()
// ==================================
bool cPluginDxr3::Initialize()
{
- device = new cDxr3Device();
+ cDxr3Device::instance();
return true;
}
@@ -274,17 +271,17 @@ cString cPluginDxr3::SVDRPCommand(const char *Command, const char *Option,
if (!strcasecmp(Command, "BRI")) {
cSettings::instance()->brightness(value);
- cDxr3Interface::instance()->updateBcsValues();
+ //cDxr3Interface::instance()->updateBcsValues();
return cString::sprintf("Brightness set to %d", value);
}
if (!strcasecmp(Command, "CON")) {
cSettings::instance()->contrast(value);
- cDxr3Interface::instance()->updateBcsValues();
+ //cDxr3Interface::instance()->updateBcsValues();
return cString::sprintf("Contrast set to %d", value);
}
if (!strcasecmp(Command, "SAT")) {
cSettings::instance()->saturation(value);
- cDxr3Interface::instance()->updateBcsValues();
+ //cDxr3Interface::instance()->updateBcsValues();
return cString::sprintf("Saturation set to %d", value);
}
#if 0
@@ -302,11 +299,11 @@ cString cPluginDxr3::SVDRPCommand(const char *Command, const char *Option,
}
#endif
if (!strcasecmp(Command, "DON")) {
- device->turnPlugin(true);
+ cDxr3Device::instance()->turnPlugin(true);
return "vdr-plugin-dxr3 turned on";
}
if (!strcasecmp(Command, "DOF")) {
- device->turnPlugin(false);
+ cDxr3Device::instance()->turnPlugin(false);
return "vdr-plugin-dxr3 turned off";
}
diff --git a/dxr3.h b/dxr3.h
index 2eb9eb7..9743e2a 100644
--- a/dxr3.h
+++ b/dxr3.h
@@ -2,6 +2,7 @@
#define _DXR3_H_
#include <vdr/i18n.h>
+#include "settings.h"
static const char MAINMENUENTRY[] = trNOOP("DXR3 Functions");
diff --git a/dxr3audio-oss.c b/dxr3audio-oss.c
index 4e70df4..d234307 100644
--- a/dxr3audio-oss.c
+++ b/dxr3audio-oss.c
@@ -20,9 +20,10 @@
#include <sys/soundcard.h>
#include <unistd.h> // for close
+#include <sys/ioctl.h>
#include "dxr3audio-oss.h"
-#include "dxr3interface.h"
+#include "dxr3device.h"
static const char *DEV_DXR3_OSS = "_ma";
@@ -31,7 +32,7 @@ void cAudioOss::openDevice()
if (open)
return;
- fd = cDxr3Interface::Dxr3Open(DEV_DXR3_OSS, O_RDWR | O_NONBLOCK);
+ fd = cDxr3Device::Dxr3Open(DEV_DXR3_OSS, O_RDWR | O_NONBLOCK);
if (!fd) {
esyslog("[dxr3-audio-oss] failed to open dxr3 audio subdevice");
@@ -99,7 +100,7 @@ void cAudioOss::setDigitalAudio(bool on)
// we need to do it this way, as we dont have access
// to the file handle for the conrtol sub device.
- cDxr3Interface::instance()->OssSetPlayMode(ioval);
+ cDxr3Device::instance()->ossSetPlayMode(ioval);
digitalAudio = on;
}
diff --git a/dxr3device.c b/dxr3device.c
index 72853d2..8177bec 100644
--- a/dxr3device.c
+++ b/dxr3device.c
@@ -20,20 +20,26 @@
*
*/
+#include <sys/ioctl.h>
+
#include "dxr3device.h"
-#include "dxr3interface.h"
#include "dxr3tools.h"
#include "dxr3osd.h"
#include "dxr3audio-oss.h"
#include "dxr3audio-alsa.h"
#include "dxr3pesframe.h"
+#include "settings.h"
+
+static const char *DEV_DXR3_OSD = "_sp";
+static const char *DEV_DXR3_VIDEO = "_mv";
+static const char *DEV_DXR3_CONT = "";
-// ==================================
-//! constructor
-cDxr3Device::cDxr3Device() : pluginOn(true), vPts(0), scrSet(false)
+cDxr3Device::cDxr3Device() : pluginOn(true), vPts(0), scrSet(false), playCount(0)
{
m_spuDecoder = NULL;
+ claimDevices();
+
// TODO: this will be later the place,
// where we will decide what kind of
// audio output system we will use.
@@ -44,18 +50,29 @@ cDxr3Device::cDxr3Device() : pluginOn(true), vPts(0), scrSet(false)
aDecoder = new cDxr3AudioDecoder();
}
-// ==================================
cDxr3Device::~cDxr3Device()
{
audioOut->releaseDevice();
delete audioOut;
delete aDecoder;
+ releaseDevices();
+
if (m_spuDecoder)
delete m_spuDecoder;
}
-// ==================================
+int cDxr3Device::Dxr3Open(const char *name, int mode, bool report_error)
+{
+ const char *filename = *cDxr3Name(name, cSettings::instance()->card());
+ int fd = open(filename, mode);
+
+ if (report_error && (fd < 0)) {
+ LOG_ERROR_STR(filename);
+ }
+ return fd;
+}
+
void cDxr3Device::MakePrimaryDevice(bool On)
{
#if VDRVERSNUM >= 10711
@@ -67,31 +84,30 @@ void cDxr3Device::MakePrimaryDevice(bool On)
}
}
-// replaying
-// ==================================
-//! do we have an mpeg2 decoder?
bool cDxr3Device::HasDecoder() const
{
- // sure we have one ;)
return true;
}
-// ==================================
-//! can we replay vdr recordings?
bool cDxr3Device::CanReplay() const
{
- // also sure...
return true;
}
-// ==================================
bool cDxr3Device::SetPlayMode(ePlayMode PlayMode)
{
dsyslog("[dxr3-device] setting playmode %d", PlayMode);
+ uint32_t ioval = EM8300_PLAYMODE_PAUSED;
+
switch (PlayMode) {
case pmNone:
audioOut->setEnabled(false);
+ CHECK(ioctl(fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval));
+ ioval = 0;
+ CHECK(ioctl(fdControl, EM8300_IOCTL_SCR_SET, &ioval));
+ scrSet = false;
+ playCount = 0;
break;
case pmAudioVideo:
@@ -106,49 +122,45 @@ bool cDxr3Device::SetPlayMode(ePlayMode PlayMode)
return true;
}
-// ==================================
int64_t cDxr3Device::GetSTC()
{
return (vPts << 1);
}
-// ==================================
void cDxr3Device::TrickSpeed(int Speed)
{
dsyslog("dxr3: device: tricspeed: %d", Speed);
}
-// ==================================
-//! clear our demux buffer
void cDxr3Device::Clear()
{
dsyslog("[dxr3-device] clear");
+
+ uint32_t ioval = EM8300_SUBDEVICE_VIDEO;
+ CHECK(ioctl(fdControl, EM8300_IOCTL_FLUSH, &ioval));
+
+ ioval = EM8300_SUBDEVICE_AUDIO;
+ CHECK(ioctl(fdControl, EM8300_IOCTL_FLUSH, &ioval));
+
cDevice::Clear();
}
-// ==================================
-//! play a recording
void cDxr3Device::Play()
{
dsyslog("[dxr3-device] play");
}
-// ==================================
-//! puts the device into "freeze frame" mode
void cDxr3Device::Freeze()
{
dsyslog("[dxr3-device] freeze");
}
-// ==================================
void cDxr3Device::Mute()
{
audioOut->mute();
cDevice::Mute();
}
-// ==================================
-//! displays the given I-frame as a still picture.
void cDxr3Device::StillPicture(const uchar *Data, int Length)
{
dsyslog("[dxr3-device] stillpciture");
@@ -168,26 +180,13 @@ void cDxr3Device::StillPicture(const uchar *Data, int Length)
}
}
-// ==================================
bool cDxr3Device::Poll(cPoller &Poller, int TimeoutMs)
{
- /*
- if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE &&
- m_DemuxDevice.GetTrickState() == DXR3_FREEZE)) {
- cCondWait::SleepMs(TimeoutMs);
- return false;
- }
- return m_DemuxDevice.Poll(TimeoutMs); // Poller.Poll(TimeoutMs);
- */
return true;
}
-// ==================================
-//! actually plays the given data block as video
int cDxr3Device::PlayVideo(const uchar *Data, int Length)
{
- static int i = 0;
-
cDxr3PesFrame frame;
frame.parse(Data, Length);
uint32_t pts = frame.GetPts();
@@ -199,24 +198,23 @@ int cDxr3Device::PlayVideo(const uchar *Data, int Length)
}
if (!scrSet && vPts != 0) {
- cDxr3Interface::instance()->SetSysClock(vPts);
+ CHECK(ioctl(fdControl, EM8300_IOCTL_SCR_SET, &vPts));
scrSet = true;
}
- cDxr3Interface::instance()->PlayVideoFrame(&frame, vPts);
+ playVideoFrame(&frame, vPts);
- if (i < 7) {
- i++;
+ if (playCount < 7) {
+ playCount++;
}
- if (i == 7) {
- cDxr3Interface::instance()->SetPlayMode();
- i = 8;
+ if (playCount == 7) {
+ //cDxr3Interface::instance()->SetPlayMode();
+ setPlayMode();
+ playCount = 8;
}
return Length;
}
-// ==================================
-// plays additional audio streams, like Dolby Digital
int cDxr3Device::PlayAudio(const uchar *Data, int Length, uchar Id)
{
cDxr3PesFrame frame;
@@ -230,35 +228,61 @@ int cDxr3Device::PlayAudio(const uchar *Data, int Length, uchar Id)
#if VDRVERSNUM >= 10710
void cDxr3Device::GetVideoSize(int &Width, int &Height, double &VideoAspect)
{
- cDxr3Interface::instance()->dimension((uint32_t&)Width, (uint32_t&)Height);
- uint32_t aspect = cDxr3Interface::instance()->GetAspectRatio();
+ uint32_t aspect;
+ CHECK(ioctl(fdControl, EM8300_IOCTL_GET_ASPECTRATIO, &aspect));
if (aspect == EM8300_ASPECTRATIO_4_3) {
VideoAspect = 4.0 / 3.0;
} else {
VideoAspect = 16.0 / 9.0;
}
+
+ Width = horizontal;
+ Height = vertical;
}
#endif
-// additional functions
-
-// ==================================
void cDxr3Device::SetVideoFormat(bool VideoFormat16_9)
{
- cDxr3Interface::instance()->SetAspectRatio(
- VideoFormat16_9 ? EM8300_ASPECTRATIO_16_9 : EM8300_ASPECTRATIO_4_3);
+ int ratio = EM8300_ASPECTRATIO_4_3;
+ if (VideoFormat16_9) {
+ ratio = EM8300_ASPECTRATIO_16_9;
+ }
+
+ int aspect;
+
+ if (cSettings::instance()->forceLetterBox()) {
+ ratio = EM8300_ASPECTRATIO_16_9;
+ }
+
+ if (Setup.VideoFormat) {
+ aspect = EM8300_ASPECTRATIO_4_3;
+#ifdef EM8300_IOCTL_SET_WSS
+ if (cSettings::Instance().GetUseWSS()) {
+ int wssmode;
+ if (ratio == EM8300_ASPECTRATIO_16_9) {
+ wssmode = EM8300_WSS_16_9;
+ } else {
+ wssmode = EM8300_WSS_OFF;
+ }
+
+ CHECK(ioctl(fdControl, EM8300_IOCTL_SET_WSS, &wssmode);
+ }
+#endif
+ } else {
+ aspect = ratio;
+ }
+
+ CHECK(ioctl(fdControl, EM8300_IOCTL_SET_ASPECTRATIO, &aspect));
+
+ SetVideoDisplayFormat(eVideoDisplayFormat(Setup.VideoDisplayFormat));
}
-// ==================================
-//! sets volume for audio output
void cDxr3Device::SetVolumeDevice(int Volume)
{
audioOut->setVolume(Volume);
}
-// ==================================
-//! sets audio channel for audio output (stereo, mono left, mono right)
void cDxr3Device::SetAudioChannelDevice(int AudioChannel)
{
audioOut->setAudioChannel(AudioChannel);
@@ -274,8 +298,6 @@ void cDxr3Device::SetDigitalAudioDevice(bool on)
audioOut->setDigitalAudio(on);
}
-// ==================================
-// get spudecoder
cSpuDecoder *cDxr3Device::GetSpuDecoder()
{
if (!m_spuDecoder && IsPrimaryDevice()) {
@@ -302,7 +324,7 @@ void cDxr3Device::turnPlugin(bool on)
}
// get full control over device
- cDxr3Interface::instance()->ClaimDevices();
+ claimDevices();
audioOut->openDevice();
// enable pes packet processing
@@ -319,7 +341,7 @@ void cDxr3Device::turnPlugin(bool on)
// release device and give control to somebody else
Tools::WriteInfoToOsd(tr("DXR3: releasing devices"));
- cDxr3Interface::instance()->ReleaseDevices();
+ releaseDevices();
audioOut->releaseDevice();
// disable pes packet processing
@@ -327,6 +349,192 @@ void cDxr3Device::turnPlugin(bool on)
}
}
+void cDxr3Device::dimension(uint32_t &hor, uint32_t &ver)
+{
+ hor = horizontal;
+ ver = vertical;
+}
+
+void cDxr3Device::setPalette(uint8_t *pal)
+{
+ CHECK(ioctl(fdSpu, EM8300_IOCTL_SPU_SETPALETTE, pal));
+}
+
+void cDxr3Device::writeSpu(const uint8_t* data, int length)
+{
+ WriteAllOrNothing(fdSpu, data, length, 1000, 10);
+}
+
+void cDxr3Device::setButton(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette)
+{
+ em8300_button_t button;
+
+ button.color = palette >> 16;
+ button.contrast = palette & 0xFFFF;
+ button.top = sy;
+ button.bottom = ey;
+ button.left = sx;
+ button.right = ex;
+
+ CHECK(ioctl(fdSpu, EM8300_IOCTL_SPU_BUTTON, &button));
+}
+
+void cDxr3Device::clearButton()
+{
+ em8300_button_t button;
+
+ // todo: why are there 1s and 2s - memset 0
+ button.color = 0;
+ button.contrast = 0;
+ button.top = 1;
+ button.bottom = 2;
+ button.left = 1;
+ button.right = 2;
+
+ CHECK(ioctl(fdSpu, EM8300_IOCTL_SPU_BUTTON, &button))
+}
+
+int cDxr3Device::ossSetPlayMode(uint32_t mode)
+{
+ return ioctl(fdControl, EM8300_IOCTL_SET_AUDIOMODE, &mode);
+}
+
+void cDxr3Device::claimDevices()
+{
+ // open control stream
+ fdControl = Dxr3Open(DEV_DXR3_CONT, O_WRONLY | O_SYNC);
+ if (fdControl < 0) {
+ esyslog("dxr3: please verify that the em8300 modules are loaded");
+ exit(1);
+ }
+
+ uploadFirmware();
+
+ ///< open multimedia streams
+ fdVideo = Dxr3Open(DEV_DXR3_VIDEO, O_WRONLY | O_SYNC);
+ fdSpu = Dxr3Open(DEV_DXR3_OSD, O_WRONLY | O_SYNC);
+
+ // everything ok?
+ if (fdVideo < 0 || fdSpu < 0) {
+ esyslog("dxr3: fatal: unable to open some em8300 devices");
+ exit(1);
+ }
+
+ // configure device based on settings
+ //ConfigureDevice();
+
+ // get bcs values from driver
+ CHECK(ioctl(fdControl, EM8300_IOCTL_GETBCS, &bcs));
+
+ playBlackFrame();
+}
+
+void cDxr3Device::releaseDevices()
+{
+ close(fdControl);
+ close(fdVideo);
+ close(fdSpu);
+
+ fdControl = fdVideo = fdSpu = -1;
+}
+
+void cDxr3Device::uploadFirmware()
+{
+ if (!cSettings::instance()->loadFirmware()) {
+ return;
+ }
+
+ dsyslog("[dxr3-interface] loading firmware");
+
+ // try to open it
+ // MICROCODE comes from makefile
+ int UCODE = open(MICROCODE, O_RDONLY);
+
+ if (UCODE < 0) {
+ esyslog("dxr3: fatal: unable to open microcode file %s", MICROCODE);
+ exit(1);
+ }
+
+ struct stat s;
+ if (fstat(UCODE, &s ) <0) {
+ esyslog("dxr3: fatal: unable to fstat microcode file %s", MICROCODE);
+ exit(1);
+ }
+
+ // read microcode
+ em8300_microcode_t em8300_microcode;
+ em8300_microcode.ucode = new char[s.st_size];
+ if (em8300_microcode.ucode == NULL) {
+ esyslog("dxr3: fatal: unable to malloc() space for microcode");
+ exit(1);
+ }
+
+ if (read(UCODE,em8300_microcode.ucode,s.st_size) < 1) {
+ esyslog("dxr3: fatal: unable to read microcode file %s", MICROCODE);
+ // free memory to avoid memory leak
+ delete[] (char*) em8300_microcode.ucode;
+ exit(1);
+ }
+
+ close(UCODE);
+ em8300_microcode.ucode_size = s.st_size;
+
+ // upload it
+ if( ioctl(fdControl, EM8300_IOCTL_INIT, &em8300_microcode) == -1) {
+ esyslog("dxr3: fatal: microcode upload failed: %m");
+ // free memory to avoid memory leak
+ delete [] (char*) em8300_microcode.ucode;
+ exit(1);
+ }
+
+ // free memory to avoid memory leak
+ delete [] (char*) em8300_microcode.ucode;
+}
+
+void cDxr3Device::setPlayMode()
+{
+ em8300_register_t reg;
+ int ioval;
+
+ ioval = EM8300_SUBDEVICE_AUDIO;
+ ioctl(fdControl, EM8300_IOCTL_FLUSH, &ioval);
+ fsync(fdVideo);
+
+ ioval = EM8300_PLAYMODE_PLAY;
+ CHECK(ioctl(fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval));
+ reg.microcode_register = 1;
+ reg.reg = 0;
+ reg.val = MVCOMMAND_SYNC;
+
+ CHECK(ioctl(fdControl, EM8300_IOCTL_WRITEREG, &reg));
+}
+
+void cDxr3Device::playVideoFrame(cDxr3PesFrame *frame, uint32_t pts)
+{
+ if (pts > 0) {
+ pts += 45000;
+ CHECK(ioctl(fdVideo, EM8300_IOCTL_VIDEO_SETPTS, &pts));
+ }
+
+ const uint8_t *data = frame->GetPayload();
+ uint32_t len = frame->GetPayloadLength();
+
+ WriteAllOrNothing(fdVideo, data, len, 1000, 10);
+}
+
+void cDxr3Device::playBlackFrame()
+{
+ extern char blackframe[];
+ extern int blackframeLength;
+
+ for (int i = 0; i < 3; i++) {
+ WriteAllOrNothing(fdVideo, (const uchar*)blackframe, blackframeLength, 1000, 10);
+ }
+
+ horizontal = 720;
+ vertical = 576;
+}
+
// Local variables:
// mode: c++
// c-file-style: "stroustrup"
diff --git a/dxr3device.h b/dxr3device.h
index 34c210b..02cfae0 100644
--- a/dxr3device.h
+++ b/dxr3device.h
@@ -26,22 +26,33 @@
//#include <string>
#include <vdr/device.h>
+#include <linux/em8300.h>
#include "dxr3audiodecoder.h"
-#include "dxr3interface.h"
#include "dxr3spudecoder.h"
#include "dxr3audio.h"
+#include "singleton.h"
+
+class cDxr3Name {
+public:
+ cDxr3Name(const char *name, int n) {
+ snprintf(buffer, sizeof(buffer), "%s%s-%d", "/dev/em8300", name, n);
+ }
+ const char *operator*() { return buffer; }
+
+private:
+ char buffer[PATH_MAX];
+};
-// ==================================
-// our device :)
/*!
cDxr3Device is the interface for VDR devices.
Is is the part, which VDR "talks" with our plugin.
*/
-class cDxr3Device : public cDevice {
+class cDxr3Device : public cDevice, public Singleton<cDxr3Device> {
public:
cDxr3Device();
~cDxr3Device();
+ static int Dxr3Open(const char *name, int mode, bool report_error = true);
virtual void MakePrimaryDevice(bool On);
// replaying
@@ -76,14 +87,41 @@ public:
void turnPlugin(bool on);
+ void dimension(uint32_t &horizontal, uint32_t &vertical);
+
+ void setPalette(uint8_t *pal);
+ void writeSpu(const uint8_t* data, int length);
+ void setButton(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette);
+ void clearButton();
+
+ int ossSetPlayMode(uint32_t mode);
+
private:
+
+ void claimDevices();
+ void releaseDevices();
+ void uploadFirmware();
+ void setPlayMode();
+ void playVideoFrame(cDxr3PesFrame *frame, uint32_t pts);
+ void playBlackFrame();
+
cDxr3AudioDecoder *aDecoder;
cDxr3SpuDecoder* m_spuDecoder;
iAudio *audioOut;
bool pluginOn;
+ em8300_bcs_t bcs;
+
+ int fdControl;
+ int fdVideo;
+ int fdSpu;
+
uint32_t vPts;
bool scrSet;
+ int playCount;
+
+ uint32_t horizontal;
+ uint32_t vertical;
};
#endif /*_DXR3_DEVICE_H_*/
diff --git a/dxr3interface.c b/dxr3interface.c
deleted file mode 100644
index 4ecd40a..0000000
--- a/dxr3interface.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * dxr3interface.c
- *
- * Copyright (C) 2002-2004 Kai Möller
- * Copyright (C) 2004-2009 Christian Gmeiner
- * Copyright (C) 2005-2008 Ville Skyttä
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include "dxr3interface.h"
-#include "dxr3osd.h"
-#include "dxr3pesframe.h"
-
-static const char *DEV_DXR3_OSD = "_sp";
-static const char *DEV_DXR3_VIDEO = "_mv";
-static const char *DEV_DXR3_CONT = "";
-
-static const int UNKNOWN_ASPECT_RATIO = 0xdeadbeef;
-
-// ==================================
-//! constructor
-cDxr3Interface::cDxr3Interface() :
- m_fdControl(-1), m_fdVideo(-1), m_fdSpu(-1)
-{
- ClaimDevices();
-}
-
-// ==================================
-//! destructor
-cDxr3Interface::~cDxr3Interface()
-{
- ReleaseDevices();
-}
-
-// audio
-int cDxr3Interface::OssSetPlayMode(uint32_t mode)
-{
- return ioctl(m_fdControl, EM8300_IOCTL_SET_AUDIOMODE, &mode);
-}
-
-// clock
-// ==================================
-void cDxr3Interface::SetSysClock(uint32_t scr)
-{
- Lock();
- CHECK(ioctl(m_fdControl, EM8300_IOCTL_SCR_SET, &scr));
- Unlock();
-}
-
-// ==================================
-uint32_t cDxr3Interface::GetSysClock()
-{
- uint32_t retval;
-
- Lock();
- CHECK(ioctl(m_fdControl, EM8300_IOCTL_SCR_GET, &retval));
- Unlock();
-
- return retval;
-}
-
-// ==================================
-void cDxr3Interface::SetPts(uint32_t pts)
-{
-
- Lock();
- CHECK(ioctl(m_fdVideo, EM8300_IOCTL_VIDEO_SETPTS, &pts));
- Unlock();
-}
-
-// ==================================
-void cDxr3Interface::SetSpuPts(uint32_t pts)
-{
- uint32_t newPts = 0;
-
- Lock();
- newPts = pts << 1; // fix for DVD subtitles
- CHECK(ioctl(m_fdSpu, EM8300_IOCTL_SPU_SETPTS, &newPts));
- Unlock();
-}
-
-// set/get functions
-// ==================================
-//! get aspect ratio
-uint32_t cDxr3Interface::GetAspectRatio() const
-{
- int ioval = 0;
-
- Lock();
-
- if (ioctl(m_fdControl, EM8300_IOCTL_GET_ASPECTRATIO, &ioval) == -1)
- {
- esyslog("dxr3: unable to get aspect ratio: %m");
- }
-
- Unlock();
-
- return ioval;
-}
-
-// ==================================
-//! set aspect ratio
-void cDxr3Interface::SetAspectRatio(uint32_t ratio)
-{
- static int requestCounter = 0;
- int aspect;
-
- Lock();
-
- if (cSettings::instance()->forceLetterBox())
- ratio = EM8300_ASPECTRATIO_16_9;
-
- if (ratio != UNKNOWN_ASPECT_RATIO)
- {
- if (ratio != m_aspectRatio && requestCounter > 50)
- {
- if (Setup.VideoFormat)
- {
- aspect = EM8300_ASPECTRATIO_4_3;
-#ifdef EM8300_IOCTL_SET_WSS
- if (cSettings::Instance().GetUseWSS())
- {
- int wssmode;
- if (ratio == EM8300_ASPECTRATIO_16_9)
- wssmode = EM8300_WSS_16_9;
- else
- wssmode = EM8300_WSS_OFF;
- if (ioctl(m_fdControl, EM8300_IOCTL_SET_WSS, &wssmode) == -1)
- {
- esyslog("dxr3: unable to set WSS: %m");
- }
- }
-#endif
- }
- else
- {
- aspect = ratio;
- }
-
- requestCounter = 0;
- if (ioctl(m_fdControl, EM8300_IOCTL_SET_ASPECTRATIO, &aspect) == -1)
- {
- esyslog("dxr3: unable to set aspect ratio: %m");
- }
- else
- {
- m_aspectRatio = ratio;
- }
- }
- else
- {
- if (ratio != m_aspectRatio)
- {
- ++requestCounter;
- }
- else
- {
- requestCounter = 0;
- }
- }
- }
-
- Unlock();
-}
-
-
-void cDxr3Interface::setDimension(uint32_t horizontal, uint32_t vertical)
-{
- if (horizontal > 0) {
- m_horizontal = horizontal;
- }
-
- if (vertical > 0) {
- m_vertical = vertical;
- }
-}
-
-void cDxr3Interface::dimension(uint32_t &horizontal, uint32_t &vertical)
-{
- horizontal = m_horizontal;
- vertical = m_vertical;
-}
-
-// play functions
-// ==================================
-//! set playing mode and start sync engine
-void cDxr3Interface::SetPlayMode()
-{
- // this is the case, when SVDRP command DOF was used and
- // should be ignored.
- if (m_fdControl == -1) {
- return;
- }
-
- em8300_register_t reg;
- int ioval;
-
- Lock();
-
- ioval = EM8300_SUBDEVICE_AUDIO;
- ioctl(m_fdControl, EM8300_IOCTL_FLUSH, &ioval);
- fsync(m_fdVideo);
-
- ioval = EM8300_PLAYMODE_PLAY;
- if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) == -1)
- {
- esyslog("dxr3: unable to set play mode: %m");
- }
- reg.microcode_register = 1;
- reg.reg = 0;
- reg.val = MVCOMMAND_SYNC;
-
- if (ioctl(m_fdControl, EM8300_IOCTL_WRITEREG, &reg) == -1)
- {
- esyslog("dxr3: unable to start em8300 sync engine: %m");
- }
-
- Unlock();
-}
-
-// ==================================
-void cDxr3Interface::Pause()
-{
- int ioval = EM8300_PLAYMODE_PAUSED;
-
- Lock();
-
- if (ioctl(m_fdControl, EM8300_IOCTL_SET_PLAYMODE, &ioval) == -1)
- {
- esyslog("dxr3: unable to set pause mode: %m");
- }
-
- Unlock();
-}
-
-// ==================================
-void cDxr3Interface::PlayVideoFrame(cDxr3PesFrame *frame, uint32_t pts)
-{
- //if (!m_VideoActive) {
- // return;
- //}
-
- if (pts > 0) {
- pts += 45000;
- this->SetPts(pts);
- }
-
- Lock();
-
- const uint8_t *data = frame->GetPayload();
- uint32_t len = frame->GetPayloadLength();
-
- WriteAllOrNothing(m_fdVideo, data, len, 1000, 10);
-
- Unlock();
-
- //SetAspectRatio(frame->GetAspectRatio());
-}
-
-// ==================================
-void cDxr3Interface::ClaimDevices()
-{
- // devices already open
- if (m_fdControl > -1 && m_fdVideo > -1 && m_fdSpu > -1) {
- return;
- }
-
- // open control stream
- m_fdControl = Dxr3Open(DEV_DXR3_CONT, O_WRONLY | O_SYNC);
- if (m_fdControl == -1)
- {
- esyslog("dxr3: please verify that the em8300 modules are loaded");
- exit(1);
- }
-
- // upload microcode to dxr3
- UploadMicroCode();
-
- ///< open multimedia streams
- m_fdVideo = Dxr3Open(DEV_DXR3_VIDEO, O_WRONLY | O_SYNC);
- m_fdSpu = Dxr3Open(DEV_DXR3_OSD, O_WRONLY | O_SYNC);
-
- // everything ok?
- if (m_fdVideo == -1 || m_fdSpu == -1)
- {
- esyslog("dxr3: fatal: unable to open some em8300 devices");
- exit(1);
- }
-
- // set default values
- m_VideoActive = false;
- m_horizontal = 720;
- m_vertical = 576;
- m_aspectRatio = UNKNOWN_ASPECT_RATIO;
-
- // configure device based on settings
- ConfigureDevice();
-
- // get bcs values from driver
- if (ioctl(m_fdControl, EM8300_IOCTL_GETBCS, &m_bcs) == -1)
- {
- esyslog("dxr3: failed to get brightness/contrast/saturation: %m");
- }
- else
- {
- dsyslog("dxr3: intf: brightness=%d,contrast=%d,saturation=%d at init",
- m_bcs.brightness, m_bcs.contrast, m_bcs.saturation);
- }
-
- PlayBlackFrame();
-}
-
-// ==================================
-void cDxr3Interface::ReleaseDevices()
-{
- if (m_fdControl > -1) {
- close(m_fdControl);
- m_fdControl = -1;
- }
-
- if (m_fdVideo > -1) {
- close(m_fdVideo);
- m_fdVideo = -1;
- }
-
- if (m_fdSpu > -1) {
- close(m_fdSpu);
- m_fdSpu = -1;
- }
-
- m_aspectRatio = UNKNOWN_ASPECT_RATIO;
-}
-
-// tools
-// ==================================
-//! play black frame on tv
-void cDxr3Interface::PlayBlackFrame()
-{
- extern char blackframe[];
- extern int blackframeLength;
-
- Lock();
-
- for (int i = 0; i < 3; i++)
- {
- if (write(m_fdVideo, blackframe, blackframeLength) == -1)
- Resuscitation();
- }
-
- m_horizontal = 720;
- m_vertical = 576;
-
- Unlock();
-}
-
-// ==================================
-//! uploadroutine for microcode
-void cDxr3Interface::UploadMicroCode()
-{
- if (!cSettings::instance()->loadFirmware()) {
- return;
- }
-
- dsyslog("[dxr3-interface] loading firmware");
- em8300_microcode_t em8300_microcode;
- struct stat s;
-
- // try to open it
- // MICROCODE comes from makefile
- int UCODE = open(MICROCODE, O_RDONLY);
-
- if (UCODE <0)
- {
- esyslog("dxr3: fatal: unable to open microcode file %s: %m",
- MICROCODE);
- exit(1);
- }
-
- if (fstat(UCODE, &s ) <0)
- {
- esyslog("dxr3: fatal: unable to fstat microcode file %s: %m",
- MICROCODE);
- exit(1);
- }
-
- // read microcode
- em8300_microcode.ucode = new char[s.st_size];
- if (em8300_microcode.ucode == NULL)
- {
- esyslog("dxr3: fatal: unable to malloc() space for microcode");
- exit(1);
- }
-
- if (read(UCODE,em8300_microcode.ucode,s.st_size) < 1)
- {
- esyslog("dxr3: fatal: unable to read microcode file %s: %m",
- MICROCODE);
- // free memory to avoid memory leak
- delete [] (char*) em8300_microcode.ucode;
- exit(1);
- }
-
- close(UCODE);
-
- em8300_microcode.ucode_size = s.st_size;
-
- // upload it
- if( ioctl(m_fdControl, EM8300_IOCTL_INIT, &em8300_microcode) == -1)
- {
- esyslog("dxr3: fatal: microcode upload failed: %m");
- // free memory to avoid memory leak
- delete [] (char*) em8300_microcode.ucode;
- exit(1);
- }
-
- // free memory to avoid memory leak
- delete [] (char*) em8300_microcode.ucode;
-}
-
-// ==================================
-//! config and setup device via ioctl calls
-void cDxr3Interface::ConfigureDevice()
-{
- uint32_t videomode = cSettings::instance()->videoMode();
-
- switch (videomode) {
- case PAL:
- dsyslog("dxr3: configure: video mode: PAL");
- break;
-
- case PAL60:
- dsyslog("dxr3: configure: video mode: PAL60");
- break;
-
- case NTSC:
- dsyslog("dxr3: configure: video mode: NTSC");
- break;
- }
-
- if (ioctl(m_fdControl, EM8300_IOCTL_SET_VIDEOMODE, &videomode) == -1) {
- esyslog("dxr3: unable to set video mode: %m");
- }
-
- // set brightness/contrast/saturation
- m_bcs.brightness = cSettings::instance()->brightness();
- m_bcs.contrast = cSettings::instance()->contrast();
- m_bcs.saturation = cSettings::instance()->saturation();
- dsyslog("dxr3: configure: brightness=%d,contrast=%d,saturation=%d",
- m_bcs.brightness, m_bcs.contrast, m_bcs.saturation);
- if (ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs) == -1) {
- esyslog("dxr3: unable to set brightness/contrast/saturation: %m");
- }
-}
-
-// ==================================
-//! reset whole hardware
-void cDxr3Interface::Resuscitation()
-{
- time_t startt = time(&startt);
- time_t endt = 0;
-
- dsyslog("dxr3: resuscitation: device failure or user initiated reset");
-
- ReleaseDevices();
- Unlock();
- ClaimDevices();
- Lock();
-
- endt = time(&endt);
- if (endt - startt > 4)
- {
- esyslog("dxr3: fatal: reopening devices took too long");
- exit(1);
- }
- dsyslog("dxr3: resuscitation: reopening devices took %ld seconds",
- endt - startt);
-}
-
-// ==================================
-void cDxr3Interface::WriteSpu(const uint8_t* pBuf, int length)
-{
- Lock();
-
- if (write(m_fdSpu, pBuf, length) == -1)
- Resuscitation();
-
- Unlock();
-}
-
-// ==================================
-void cDxr3Interface::SetButton(uint16_t sx, uint16_t sy, uint16_t ex,
- uint16_t ey, uint32_t palette)
-{
- em8300_button_t button;
-
- button.color = palette >> 16;
- button.contrast = palette & 0xFFFF;
- button.top = sy;
- button.bottom = ey;
- button.left = sx;
- button.right = ex;
-
- CHECK(ioctl(m_fdSpu, EM8300_IOCTL_SPU_BUTTON, &button));
-}
-
-// ==================================
-void cDxr3Interface::ClearButton()
-{
- em8300_button_t button;
-
- button.color = 0;
- button.contrast = 0;
- button.top = 1;
- button.bottom = 2;
- button.left = 1;
- button.right = 2;
-
- CHECK(ioctl(m_fdSpu, EM8300_IOCTL_SPU_BUTTON, &button));
-}
-
-// ==================================
-void cDxr3Interface::SetPalette(unsigned int *pal)
-{
- CHECK(ioctl(m_fdSpu, EM8300_IOCTL_SPU_SETPALETTE, (uint8_t*)pal));
-}
-
-// helper functions for dxr3 main osd screen
-// ==================================
-//! reset dxr3 card
-void cDxr3Interface::ResetHardware()
-{
- Lock();
-
- isyslog("dxr3: hardware reset requested");
- Resuscitation();
-
- Unlock();
-}
-
-void cDxr3Interface::updateBcsValues()
-{
- // update m_bcs with values from settings
- m_bcs.brightness = cSettings::instance()->brightness();
- m_bcs.contrast = cSettings::instance()->contrast();
- m_bcs.saturation = cSettings::instance()->saturation();
-
- // update bcs values in hardware
- CHECK(ioctl(m_fdControl, EM8300_IOCTL_SETBCS, &m_bcs));
-}
-
-// ==================================
-//! get brightness
-int cDxr3Interface::GetBrightness()
-{
- return m_bcs.brightness;
-}
-
-// ==================================
-//! get contrast
-int cDxr3Interface::GetContrast()
-{
- return m_bcs.contrast;
-}
-
-// ==================================
-//! get saturation
-int cDxr3Interface::GetSaturation()
-{
- return m_bcs.saturation;
-}
-
-// ==================================
-cMutex* cDxr3Interface::m_pMutex = new cMutex;
-
-// Local variables:
-// mode: c++
-// c-file-style: "stroustrup"
-// c-file-offsets: ((inline-open . 0))
-// tab-width: 4;
-// indent-tabs-mode: nil
-// End:
diff --git a/dxr3interface.h b/dxr3interface.h
deleted file mode 100644
index 3b3191b..0000000
--- a/dxr3interface.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * dxr3interface.h
- *
- * Copyright (C) 2002-2004 Kai Möller
- * Copyright (C) 2004-2009 Christian Gmeiner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#ifndef _DXR3_INTERFACE_H_
-#define _DXR3_INTERFACE_H_
-
-#include <linux/em8300.h>
-#include <sys/ioctl.h>
-#include <linux/limits.h>
-
-#include <vdr/tools.h>
-#include "settings.h"
-
-// ==================================
-class cDxr3PesFrame;
-
-class cDxr3Name {
-public:
- cDxr3Name(const char *name, int n) {
- snprintf(buffer, sizeof(buffer), "%s%s-%d", "/dev/em8300", name, n);
- }
- const char *operator*() { return buffer; }
-
-private:
- char buffer[PATH_MAX];
-};
-
-// ==================================
-//! interafce to dxr3-card
-/*!
- cDxr3Interface is the interface to the dxr3
- driver and so to the card,
- so this is the layer between plugin and driver.
-*/
-class cDxr3Interface : public Singleton<cDxr3Interface> {
-public:
- cDxr3Interface();
- ~cDxr3Interface();
-
- static int Dxr3Open(const char *name, int mode, bool report_error = true) {
- const char *filename = *cDxr3Name(name, cSettings::instance()->card());
- int fd = open(filename, mode);
-
- if (report_error && (fd < 0)) {
- LOG_ERROR_STR(filename);
- }
- return fd;
- }
-
- // audio
- int OssSetPlayMode(uint32_t mode);
-
- // clock
- void SetSysClock(uint32_t scr);
- uint32_t GetSysClock();
- void SetPts(uint32_t pts);
- void SetSpuPts(uint32_t pts);
-
- // state changes
- void EnableVideo()
- {
- m_VideoActive = true;
- }
- void DisableVideo()
- {
- m_VideoActive = false;
- }
-
- // set/get functions
- uint32_t GetAspectRatio() const;
- void SetAspectRatio(uint32_t ratio);
-
- void setDimension(uint32_t horizontal, uint32_t vertical);
- void dimension(uint32_t &horizontal, uint32_t &vertical);
-
- // play functions
- void SetPlayMode();
- void Pause();
- void PlayVideoFrame(cDxr3PesFrame *frame, uint32_t pts);
-
- // device access
- void ClaimDevices();
- void ReleaseDevices();
-
- // tools
- void PlayBlackFrame();
-
- // osd/spu
- void WriteSpu(const uint8_t* pBuf, int length);
- void SetButton(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey,
- uint32_t palette);
- void ClearButton();
- void SetPalette(unsigned int *pal);
-
- // helper functions for dxr3 main osd screen
- void ResetHardware();
-
- void updateBcsValues();
- // get brightness/contrast/saturation
- int GetBrightness();
- int GetContrast();
- int GetSaturation();
-
-private:
- // file handles
- int m_fdControl; ///< filehandle for contol fifo of dxr3 card
- int m_fdVideo; ///< filehandle for video fifo of dxr3 card
- int m_fdSpu; ///< filehandle for spu fifo of dxr3 card
-
- uint32_t m_aspectRatio; ///< current used aspect ratio
- uint32_t m_horizontal; ///< horizontal size of current videostream
- uint32_t m_vertical; ///< vertical size of current videostream
- bool m_VideoActive; ///< is video active?
-
- // bcs
- em8300_bcs_t m_bcs; ///< BrightnessContrastSaturation values
-
- void UploadMicroCode();
- void ConfigureDevice();
- void Resuscitation();
-
- static cMutex* m_pMutex; ///< mutex for dxr3interface
-
- static void Lock()
- {
- cDxr3Interface::m_pMutex->Lock();
- }
- static void Unlock()
- {
- cDxr3Interface::m_pMutex->Unlock();
- }
-};
-
-#endif /*_DXR3_INTERFACE_H_*/
-
-// Local variables:
-// mode: c++
-// c-file-style: "stroustrup"
-// c-file-offsets: ((inline-open . 0))
-// tab-width: 4;
-// indent-tabs-mode: nil
-// End:
diff --git a/dxr3osd.c b/dxr3osd.c
index 77ddfe5..1130a9a 100644
--- a/dxr3osd.c
+++ b/dxr3osd.c
@@ -26,9 +26,9 @@
*/
#include "dxr3osd.h"
-#include "dxr3interface.h"
#include "spuencoder.h"
#include "scaler.h"
+#include "dxr3device.h"
// ==================================
// ! create osd at (Left, Top, Level)
@@ -201,7 +201,7 @@ void cDxr3Osd::Flush()
bmap->Clean();
uint32_t horizontal, vertical;
- cDxr3Interface::instance()->dimension(horizontal, vertical);
+ cDxr3Device::instance()->dimension(horizontal, vertical);
int top = Top();
int left = Left();
diff --git a/dxr3spudecoder.c b/dxr3spudecoder.c
index f01e718..32b5c55 100644
--- a/dxr3spudecoder.c
+++ b/dxr3spudecoder.c
@@ -26,7 +26,6 @@
#include <math.h>
#include "dxr3spudecoder.h"
-#include "dxr3interface.h"
#include "dxr3tools.h"
// ==================================
diff --git a/spuencoder.c b/spuencoder.c
index ed44b05..ec2d965 100644
--- a/spuencoder.c
+++ b/spuencoder.c
@@ -25,8 +25,8 @@
*/
#include "spuencoder.h"
-#include "dxr3interface.h"
#include "dxr3tools.h"
+#include "dxr3device.h"
static const uint8_t CMD_FORCE_DISPLAYING = 0x00;
static const uint8_t CMD_STOP_DISPLAYING = 0x02;
@@ -64,7 +64,7 @@ void cSpuEncoder::clearOsd()
// TODO: osd button handling
- cDxr3Interface::instance()->WriteSpu((uchar *)&d, 10);
+ cDxr3Device::instance()->writeSpu((uchar *)&d, 10);
}
void cSpuEncoder::encode(cBitmap *bmap, int top, int left)
@@ -133,7 +133,7 @@ void cSpuEncoder::encode(cBitmap *bmap, int top, int left)
// we are ready to send generated spu data
dsyslog("[dxr3-spuencoder] spu packet size %d (bytes). %d left", written, (MAX_SPU_DATA - written));
- cDxr3Interface::instance()->WriteSpu((uchar *)&spu, written);
+ cDxr3Device::instance()->writeSpu((uchar *)&spu, written);
if (data) {
delete data;
@@ -251,7 +251,7 @@ void cSpuEncoder::generateColorPalette()
}
// upload color palette
- cDxr3Interface::instance()->SetPalette(palcolors);
+ cDxr3Device::instance()->setPalette((uint8_t *)palcolors);
}
void cSpuEncoder::generateSpuData(bool topAndBottom) throw (char const* )