diff options
author | austriancoder <austriancoder> | 2005-08-15 17:28:49 +0000 |
---|---|---|
committer | austriancoder <austriancoder> | 2005-08-15 17:28:49 +0000 |
commit | 290038f3de13b728cab6d3db7729078482903844 (patch) | |
tree | b83287be6ad0602f7f73a91c11b36074e5062be0 /dxr3device.c | |
parent | 8955b4dfa419698ecb853bb8f1cdc1fe96d206d6 (diff) | |
download | vdr-plugin-dxr3-290038f3de13b728cab6d3db7729078482903844.tar.gz vdr-plugin-dxr3-290038f3de13b728cab6d3db7729078482903844.tar.bz2 |
HEAD = 0.2.3 release, because i want to start my coding with this codebase
Diffstat (limited to 'dxr3device.c')
-rw-r--r-- | dxr3device.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/dxr3device.c b/dxr3device.c new file mode 100644 index 0000000..39467ed --- /dev/null +++ b/dxr3device.c @@ -0,0 +1,467 @@ +/* + * dxr3device.c + * + * Copyright (C) 2002-2004 Kai Möller + * Copyright (C) 2004 Christian Gmeiner + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "dxr3device.h" +#include "dxr3configdata.h" +#include "dxr3interface.h" +#include "dxr3tools.h" +#include "dxr3osd.h" + +extern "C" +{ +#include <jpeglib.h> +} + +// ================================== +//! constructor +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) +{ + new cDxr3OsdProvider(); +} + +// replaying +// ================================== +//! does we have an mpeg2 devocer? +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) +{ + if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED) + { + Tools::WriteInfoToOsd(tr("DXR3: releasing devices")); + 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(); + } + + if (cDxr3ConfigData::Instance().GetUseDigitalOut()) + { + if (cDxr3ConfigData::Instance().GetAc3OutPut() && m_CalledBySet) + { + isyslog("dxr3: Setting AC3 audio mode"); + cDxr3Interface::Instance().SetAudioDigitalAC3(); // !!! FIXME + } + else + { + isyslog("dxr3: Setting digital PCM audio mode"); + cDxr3Interface::Instance().SetAudioDigitalPCM(); + cDxr3ConfigData::Instance().SetAc3OutPut(0); + } + } + else + { + isyslog("dxr3: Setting analog audio mode"); + cDxr3Interface::Instance().SetAudioAnalog(); + } + + return true; +} + +// ================================== +int64_t cDxr3Device::GetSTC() +{ + return cDxr3Interface::Instance().GetPts(); +} + +// ================================== +void cDxr3Device::TrickSpeed(int Speed) +{ + dsyslog("dxr3: device: tricspeed: %d", Speed); + + m_DemuxDevice.SetTrickMode(DXR3_FAST, Speed); + + /* + 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; + ///< free buffer + 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) +{ + if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && + m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || + cDxr3Interface::Instance().IsExternalReleased()) + { +#if VDRVERSNUM >= 10314 + cCondWait::SleepMs(TimeoutMs); +#else + usleep(TimeoutMs * 1000); +#endif + return false; + } + 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 -1; + } + + 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 +#if VDRVERSNUM >= 10318 +int cDxr3Device::PlayAudio(const uchar *Data, int Length) +#else +void cDxr3Device::PlayAudio(const uchar *Data, int Length) +#endif +{ + int retLength = 0; +#if VDRVERSNUM >= 10318 + int origLength = Length; +#endif + + m_AC3Present = true; + + if ((m_DemuxDevice.GetDemuxMode() == DXR3_DEMUX_TRICK_MODE && + m_DemuxDevice.GetTrickState() == DXR3_FREEZE) || + cDxr3Interface::Instance().IsExternalReleased()) + { + //usleep(1000000); +#if VDRVERSNUM >= 10318 + return 0; +#else + return; +#endif + } + + 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(), true); + } + } + else + { + if (m_PlayMode == pmAudioOnly) + { + retLength = m_DemuxDevice.DemuxAudioPes((const uint8_t*) Data, Length); + } 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); + } + } + +#if VDRVERSNUM >= 10318 + return origLength; +#endif +} + +// 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) != 1) + { + LOG_ERROR_STR(FileName); + } + } + fclose(f); + } + else + { + return false; + } + + delete Data; + return true; +} + +// ================================== +void cDxr3Device::SetVideoFormat(bool VideoFormat16_9) +{ + // Do we need this function? +} + +// ================================== +//! sets volume for audio output +void cDxr3Device::SetVolumeDevice(int Volume) +{ + cDxr3Interface::Instance().SetVolume(Volume); +} + +// ================================== +//! sets audio channel for audio output (stero, mono left, mono right) +void cDxr3Device::SetAudioChannelDevice(int AudioChannel) +{ + cDxr3Interface::Instance().SetAudioChannel(AudioChannel); +} +int cDxr3Device::GetAudioChannelDevice(void) +{ + return cDxr3Interface::Instance().GetAudioChannel(); +} + +// ================================== +// get spudecoder +cSpuDecoder *cDxr3Device::GetSpuDecoder(void) +{ + if (!m_spuDecoder && IsPrimaryDevice()) + { + m_spuDecoder = new cDxr3SpuDecoder(); + } + return m_spuDecoder; +} + +// Local variables: +// mode: c++ +// c-file-style: "stroustrup" +// c-file-offsets: ((inline-open . 0)) +// indent-tabs-mode: t +// End: |