summaryrefslogtreecommitdiff
path: root/dxr3device.c
diff options
context:
space:
mode:
authoraustriancoder <austriancoder>2004-08-05 23:05:21 +0000
committeraustriancoder <austriancoder>2004-08-05 23:05:21 +0000
commitc47666d42f7972e1b51f9de61ce0fa27c72f3127 (patch)
treee34a87e37901b7f892fb6f330ccb15bcba30039b /dxr3device.c
downloadvdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.gz
vdr-plugin-dxr3-c47666d42f7972e1b51f9de61ce0fa27c72f3127.tar.bz2
initial import
Diffstat (limited to 'dxr3device.c')
-rw-r--r--dxr3device.c472
1 files changed, 472 insertions, 0 deletions
diff --git a/dxr3device.c b/dxr3device.c
new file mode 100644
index 0000000..b7e2553
--- /dev/null
+++ b/dxr3device.c
@@ -0,0 +1,472 @@
+#include "dxr3device.h"
+#include "dxr3configdata.h"
+#include "dxr3interface.h"
+#include "dxr3tools.h"
+#include "dxr3log.h"
+
+extern "C"
+{
+ #include <jpeglib.h>
+}
+
+// ==================================
+cDxr3Device::cDxr3Device() : m_DemuxDevice(cDxr3Interface::Instance())
+{
+ m_Offset = 0;
+ m_strBuf.erase(m_strBuf.begin(), m_strBuf.end());
+ m_spuDecoder = NULL;
+ m_AC3Present = false;
+ m_CalledBySet = false;
+}
+
+// ==================================
+cDxr3Device::~cDxr3Device()
+{
+ if (m_spuDecoder)
+ {
+ delete m_spuDecoder;
+ }
+}
+
+// ==================================
+void cDxr3Device::MakePrimaryDevice(bool On)
+{
+#if VDRVERSNUM >= 10307
+ new cDxr3OsdProvider();
+#endif
+}
+
+// replaying
+// ==================================
+bool cDxr3Device::HasDecoder() const
+{
+ // sure we have one ;)
+ return true;
+}
+
+// ==================================
+bool cDxr3Device::CanReplay() const
+{
+ // also sure...
+ return true;
+}
+
+// ==================================
+bool cDxr3Device::SetPlayMode(ePlayMode PlayMode)
+{
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ switch (PlayMode)
+ {
+ case pmNone:
+ cLog::Instance() << "cDxr3Device::SetPlayMode audio/video from decoder\n";
+ break;
+
+ case pmAudioVideo:
+ cLog::Instance() << "cDxr3Device::SetPlayMode audio/video from player\n";
+ break;
+
+ case pmAudioOnly:
+ cLog::Instance() << "cDxr3Device::SetPlayMode audio only from player, video from decoder\n";
+ break;
+
+ case pmAudioOnlyBlack:
+ cLog::Instance() << "cDxr3Device::SetPlayMode audio only from player, no video (black screen)\n";
+ break;
+
+ case pmExtern_THIS_SHOULD_BE_AVOIDED:
+ cLog::Instance() << "cDxr3Device::SetPlayMode this should be avoided\n";
+ break;
+
+ #if VDRVERSNUM >= 10307
+ case pmVideoOnly:
+ cLog::Instance() << "cDxr3Device::SetPlayMode video only from player, audio from decoder\n";
+ break;
+ #endif
+ }
+ }
+
+ if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED)
+ {
+ Tools::WriteInfoToOsd("Dxr3: Releasing devices\n");
+ cDxr3Interface::Instance().ExternalReleaseDevices();
+ }
+ else
+ {
+ cDxr3Interface::Instance().ExternalReopenDevices();
+ }
+
+ // should this relay be here?
+ m_Offset = 0;
+ m_AC3Present = false;
+ m_strBuf.erase(m_strBuf.begin(), m_strBuf.end());
+
+ if (PlayMode == pmAudioOnlyBlack)
+ {
+ m_PlayMode = pmAudioOnly;
+ }
+ else
+ {
+ m_PlayMode = PlayMode;
+ }
+
+ if (m_PlayMode == pmAudioVideo)
+ {
+ m_DemuxDevice.SetReplayMode();
+ }
+
+ if (m_PlayMode == pmNone)
+ {
+ m_DemuxDevice.Stop();
+ }
+
+ cLog::Instance() << "Setting audio mode...";
+
+ if (cDxr3ConfigData::Instance().GetUseDigitalOut())
+ {
+ if (cDxr3ConfigData::Instance().GetAc3OutPut() && m_CalledBySet)
+ {
+ cDxr3Interface::Instance().SetAudioDigitalAC3(); // !!! FIXME
+ cLog::Instance() << "ac3\n";
+ }
+ else
+ {
+ cDxr3Interface::Instance().SetAudioDigitalPCM();
+ cDxr3ConfigData::Instance().SetAc3OutPut(0);
+ cLog::Instance() << "digital pcm\n";
+ }
+ }
+ else
+ {
+ cDxr3Interface::Instance().SetAudioAnalog();
+ cLog::Instance() << "analog\n";
+ }
+
+ return true;
+}
+
+// ==================================
+int64_t cDxr3Device::GetSTC()
+{
+ return cDxr3Interface::Instance().GetSysClock();
+}
+
+// ==================================
+void cDxr3Device::TrickSpeed(int Speed)
+{
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3Device::TrickSpeed(int Speed): " << Speed << "\n";
+ }
+
+
+ m_DemuxDevice.SetTrickMode(DXR3_FAST, Speed);
+
+
+/*
+ switch (Speed)
+ {
+ case 6:
+ cLog::Instance() << "Trickspeed: 1x vorwärts\n";
+ break;
+
+ case 3:
+ cLog::Instance() << "Trickspeed: 2x vorwärts\n";
+ break;
+
+ case 1:
+ cLog::Instance() << "Trickspeed: 3x vorwärts\n";
+ break;
+ };
+*/
+/*
+ 6 ... 1x vowärts
+ 3 ... 2x vowärts
+ 1 ... 2x vowärts
+
+ 6 ... 1x rückwärts
+ 3 ... 2x rückwärts
+ 1 ... 3x rückwärts
+
+ 8 ... 1x vorwörts, wenn Pause gedrückt
+*/
+
+ /*
+#define EM8300_PLAYMODE_PAUSED 1
+#define EM8300_PLAYMODE_SLOWFORWARDS 2
+#define EM8300_PLAYMODE_SLOWBACKWARDS 3
+#define EM8300_PLAYMODE_SINGLESTEP 4
+ */
+ /*
+ if (Speed == 8)
+ {
+ cDxr3Interface::Instance().SingleStep();
+ }
+ else
+ {
+ m_DemuxDevice.SetTrickMode(DXR3_FAST);
+ }*/
+}
+
+// ==================================
+// clear our demux buffer
+void cDxr3Device::Clear()
+{
+ m_DemuxDevice.Clear();
+ m_Offset = 0;
+ m_strBuf.erase(m_strBuf.begin(), m_strBuf.end());
+}
+
+// ==================================
+// play a recording
+void cDxr3Device::Play()
+{
+ m_DemuxDevice.SetReplayMode();
+ m_Offset = 0;
+ m_strBuf.erase(m_strBuf.begin(), m_strBuf.end());
+}
+
+// ==================================
+// puts the device into "freeze frame" mode
+void cDxr3Device::Freeze()
+{
+ m_DemuxDevice.SetTrickMode(DXR3_FREEZE);
+}
+
+// ==================================
+void cDxr3Device::Mute()
+{
+ m_DemuxDevice.SetTrickMode(DXR3_FAST);
+}
+
+// ==================================
+// displays the given I-frame as a still picture.
+void cDxr3Device::StillPicture(const uchar *Data, int Length)
+{
+ m_DemuxDevice.StillPicture(Data, Length);
+}
+
+// ==================================
+bool cDxr3Device::Poll(cPoller &Poller, int TimeoutMs)
+{
+ return m_DemuxDevice.Poll(TimeoutMs); // Poller.Poll(TimeoutMs);
+}
+
+// ==================================
+// actually plays the given data block as video
+int cDxr3Device::PlayVideo(const uchar *Data, int Length)
+{
+ int retLength = 0;
+ int origLength = Length;
+
+ if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE &&
+ m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || cDxr3Interface::Instance().IsExternalReleased())
+ {
+ // Why is here so a huge time waster?
+ //usleep(1000000);
+ return 0;
+ }
+
+ if (m_strBuf.length())
+ {
+ m_strBuf.append((const char*)Data, Length);
+
+ if (m_PlayMode == pmAudioOnly)
+ {
+ retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)m_strBuf.data(), m_strBuf.length());
+ }
+ else
+ {
+ retLength = m_DemuxDevice.DemuxPes((const uint8_t*)m_strBuf.data(), m_strBuf.length());
+ }
+ }
+ else
+ {
+ if (m_PlayMode == pmAudioOnly)
+ {
+ retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*)Data, Length);
+ }
+ else
+ {
+ retLength = m_DemuxDevice.DemuxPes((const uint8_t*)Data, Length);
+ }
+ }
+
+ Length -= retLength;
+
+ if (m_strBuf.length())
+ {
+ m_strBuf.erase(m_strBuf.length() - retLength, retLength);
+ }
+ else
+ {
+ if (Length)
+ {
+ m_strBuf.append((const char*)(Data + retLength), Length);
+ }
+ }
+
+ return origLength;
+}
+
+// ==================================
+// plays additional audio streams, like Dolby Digital
+void cDxr3Device::PlayAudio(const uchar *Data, int Length)
+{
+ int retLength = 0;
+
+ #if VDRVERSNUM < 10307
+ if (!m_AC3Present)
+ {
+ Interface->Write(Interface->Width() / 2, 0, "AC3", clrRed);
+ }
+ #endif
+
+ m_AC3Present = true;
+
+ if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE &&
+ m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || cDxr3Interface::Instance().IsExternalReleased())
+ {
+ //usleep(1000000);
+ return;
+ }
+
+ if (m_strBuf.length())
+ {
+ m_strBuf.append((const char*)Data, Length);
+ retLength = m_DemuxDevice.DemuxPes((const uint8_t*)m_strBuf.data(), m_strBuf.length(), true);
+ }
+ else
+ {
+ retLength = m_DemuxDevice.DemuxPes((const uint8_t*)Data, Length, true);
+ }
+
+ Length -= retLength;
+
+ if (m_strBuf.length())
+ {
+ m_strBuf.erase(m_strBuf.length() - retLength, retLength);
+ }
+ else
+ {
+ if (Length)
+ {
+ m_strBuf.append((const char*)(Data + retLength), Length);
+ }
+ }
+}
+
+// addition functions
+// ==================================
+// capture a single frame as an image
+bool cDxr3Device::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
+{
+ int w = SizeX;
+ int h = SizeY;
+ unsigned char *Data = new unsigned char[w*h*3];
+ memset(Data, 0, w*h*3);
+
+ // we could get a I-Frame and save it
+ //m_DemuxDevice.StillPicture(Data, 100*1024);
+
+ isyslog("grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, w, h);
+ FILE *f = fopen(FileName, "wb");
+ if (f)
+ {
+ if (Jpeg)
+ {
+ // write JPEG file:
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ jpeg_stdio_dest(&cinfo, f);
+ cinfo.image_width = w;
+ cinfo.image_height = h;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, Quality, true);
+ jpeg_start_compress(&cinfo, true);
+
+ int rs = w * 3;
+ JSAMPROW rp[h];
+ for (int k = 0; k < h; k++)
+ {
+ rp[k] = &Data[rs * k];
+ }
+ jpeg_write_scanlines(&cinfo, rp, h);
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ }
+ else
+ {
+ // write PNM file:
+ if (fprintf(f, "P6\n%d\n%d\n255\n", w, h) < 0 || fwrite(Data, w * h * 3, 1, f) < 0)
+ {
+ LOG_ERROR_STR(FileName);
+ }
+ }
+ fclose(f);
+ }
+ else
+ {
+ return false;
+ }
+
+ delete Data;
+ return true;
+}
+
+// ==================================
+void cDxr3Device::SetVideoFormat(bool VideoFormat16_9)
+{
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3Device::SetPlayMode(ePlayMode PlayMode)() done\n";
+ }
+ // Do we need this function?
+}
+
+// ==================================
+// sets volume for audio output
+void cDxr3Device::SetVolumeDevice(int Volume)
+{
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "change volume to " << Volume << " \n";
+ }
+ cDxr3Interface::Instance().SetVolume(Volume);
+}
+
+// ==================================
+// get spudecoder
+cSpuDecoder *cDxr3Device::GetSpuDecoder(void)
+{
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3Device::GetSpuDecoder";
+ }
+
+ if (!m_spuDecoder && IsPrimaryDevice())
+ {
+ if (cDxr3ConfigData::Instance().GetDebug())
+ {
+ cLog::Instance() << "cDxr3Device::GetSpuDecoder: ok";
+ }
+ m_spuDecoder = new cDxr3SpuDecoder();
+ }
+ return m_spuDecoder;
+}
+
+#if VDRVERSNUM < 10307
+// ==================================
+// return osd
+cOsdBase *cDxr3Device::NewOsd(int x, int y)
+{
+ return m_DemuxDevice.NewOsd(x, y);
+}
+#endif
+