OBJECTS1 = main.o command.o log.o tcp.o dsock.o thread.o timers.o i18n.o \
message.o messagequeue.o \
vdr.o recording.o channel.o rectimer.o event.o directory.o \
- player.o demuxer.o stream.o vfeed.o afeed.o afeedr.o \
+ player.o demuxer.o stream.o vfeed.o afeed.o afeedr.o draintarget.o \
viewman.o box.o region.o colour.o view.o \
vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o \
vtimerlist.o vtimeredit.o voptionsmenu.o vrecordingmenu.o vquestion.o \
audioEnabled = 1;
}
+#ifndef NEW_DEMUXER
int AFeed::init(int tfd)
{
fd = tfd;
return 1;
}
+#else
+int AFeed::init(DrainTarget* tdt)
+{
+ dt = tdt;
+ return 1;
+}
+#endif
int AFeed::shutdown()
{
if (audioEnabled)
{
+#ifndef NEW_DEMUXER
alen = Demuxer::getInstance()->writeAudio(fd); // FIXME ?
+#else
+ alen = Demuxer::getInstance()->writeAudio(dt); // FIXME ?
+#endif
if (alen)
{
#include "log.h"
#include "demuxer.h"
#include "callback.h"
+#include "draintarget.h"
#ifdef WIN32
#include "threadwin.h"
#include "threadp.h"
#endif
+
class AFeed : public Thread_TYPE
{
public:
AFeed(Callback* tcb);
-
+#ifndef NEW_DEMUXER
int init(int fd);
+#else
+ int init(DrainTarget* tdt);
+#endif
int shutdown();
int start();
void threadMethod();
void threadPostStopCleanup() {};
int audioEnabled;
+#ifndef NEW_DEMUXER
int fd;
+#else
+ DrainTarget* dt;
+#endif
Callback& cb;
};
{
}
+#ifndef NEW_DEMUXER
int AFeedR::init(int tfd)
{
fd = tfd;
return 1;
}
+#else
+int AFeedR::init(DrainTarget* tdt)
+{
+ dt = tdt;
+ return 1;
+}
+#endif
+
int AFeedR::shutdown()
{
while(1)
{
+#ifndef NEW_DEMUXER
alen = stream.drain(fd);
+#else
+ alen = stream.drain(dt);
+ threadCheckExit();
+#endif
if (alen)
{
#include "log.h"
#include "callback.h"
#include "stream.h"
+#include "draintarget.h"
#ifdef WIN32
#include "threadwin.h"
{
public:
AFeedR(Callback* tcb, Stream* tstream);
-
+#ifndef NEW_DEMUXER
int init(int fd);
+#else
+ int init(DrainTarget* tdt);
+#endif
int shutdown();
int start();
private:
void threadMethod();
void threadPostStopCleanup() {};
-
+#ifndef NEW_DEMUXER
int fd;
+#else
+ DrainTarget* dt;
+#endif
Callback& cb;
Stream& stream;
};
#include <stdio.h>
#include "defines.h"
#include "log.h"
+#include "draintarget.h"
typedef struct
{
unsigned char lfe;
} audio_volume;
-class Audio
+class Audio : public DrainTarget
{
public:
Audio();
}
#endif
+
+
+// unused
+UINT AudioMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos)
+{
+ return 0;
+}
int write(char *buf, int len);
int getFD();
+ //Writing Data to Audiodevice -- unused in MVP code so far
+ virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+ virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; };
+
#ifdef DEV
int test();
#endif
*/
#include "audiowin.h"
+#include "videowin.h"
+
+
+
+
AudioWin::AudioWin()
{
- if (instance) return;
initted = 0;
+ firstsynched=false;
+
+
}
AudioWin::~AudioWin()
{
+
}
int AudioWin::init(UCHAR tstreamType)
int AudioWin::play()
{
if (!initted) return 0;
+ firstsynched=false;
+
return 1;
}
int AudioWin::mute()
{
if (!initted) return 0;
+ ((VideoWin*)Video::getInstance())->SetAudioState(false);
return 1;
}
int AudioWin::unMute()
{
if (!initted) return 0;
+ ((VideoWin*)Video::getInstance())->SetAudioState(true);
return 1;
}
+UINT AudioWin::DeliverMediaSample(MediaPacket packet,
+ UCHAR* buffer,
+ UINT *samplepos)
+{
+ /*First Check, if we have an audio sample*/
+ VideoWin *vw=(VideoWin*)Video::getInstance();
+ IMediaSample* ms=NULL;
+ REFERENCE_TIME reftime1=0;
+ REFERENCE_TIME reftime2=0;
+
+ UINT headerstrip=0;
+ if (packet.disconti) {
+ firstsynched=false;
+ vw->DeliverVideoMediaSample();
+ }
+
+
+
+ /*Inspect PES-Header */
+/* UINT header_length=buffer[(packet.pos_buffer+8)%bufferlength]+8/*is this right*;
+*/
+ if (*samplepos==0) {//stripheader
+ headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
+ *samplepos+=headerstrip;
+ if ( packet.synched ) {
+ vw->DeliverAudioMediaSample();//write out old data
+ if (packet.presentation_time<0) { //Preroll?
+ *samplepos=packet.length;//if we have not processed at least one
+ return packet.length;//synched packet ignore it!
+ }
+
+ reftime1=packet.presentation_time;
+ reftime2=reftime1+1;
+ firstsynched=true;
+ } else {
+ if (!firstsynched) {//
+ *samplepos=packet.length;//if we have not processed at least one
+ return packet.length;//synched packet ignore it!
+ }
+ }
+ }
+ BYTE *ms_buf;
+ UINT ms_length;
+ UINT ms_pos;
+ UINT haveToCopy;
+ if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample
+ samplepos=0;
+ MILLISLEEP(10);
+ return 0;
+ }
+ ms_pos=ms->GetActualDataLength();
+ ms_length=ms->GetSize();
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+ if ((ms_length-ms_pos)<1) {
+ vw->DeliverAudioMediaSample(); //we are full!
+ if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample
+ samplepos=0;
+ MILLISLEEP(10);
+ return 0;
+ }
+ ms_pos=ms->GetActualDataLength();
+ ms_length=ms->GetSize();
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+ }
+ ms->GetPointer(&ms_buf);
+
+ if (ms_pos==0) {//will only be changed on first packet
+ if (packet.disconti) {
+ ms->SetDiscontinuity(TRUE);
+ } else {
+ ms->SetDiscontinuity(FALSE);
+ }
+ if (packet.synched) {
+ ms->SetSyncPoint(TRUE);
+ ms->SetTime(&reftime1,&reftime2);
+ //ms->SetTime(NULL,NULL);
+ ms->SetMediaTime(NULL, NULL);
+ }else {
+ ms->SetSyncPoint(FALSE);
+ ms->SetTime(NULL,NULL);
+ ms->SetMediaTime(NULL, NULL);
+ ms->SetSyncPoint(TRUE);
+ }
+ }
+
+
+ memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
+ ms->SetActualDataLength(haveToCopy+ms_pos);
+
+ *samplepos+=haveToCopy;
+
+ return haveToCopy+headerstrip;
+
+}
+
+long long AudioWin::SetStartOffset(long long curreftime, bool *rsync){
+ VideoWin *vw=(VideoWin*)Video::getInstance();
+ return vw->SetStartAudioOffset(curreftime,rsync);
+}
+
#ifdef DEV
int AudioWin::test()
{
int write(char *buf, int len);
int getFD();
+ // Writing Data to Audiodevice
+ virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+ virtual long long SetStartOffset(long long curreftime, bool *rsync);
+
+private:
+ bool firstsynched;
#ifdef DEV
int test();
#endif
*/
#include "command.h"
+#ifdef WIN32
+#include "remotewin.h"
+#endif
Command* Command::instance = NULL;
// something happened, lock and process
#ifndef WIN32
- pthread_mutex_lock(&masterLock);
+ pthread_mutex_lock(&masterLock);
#else
- WaitForSingleObject(masterLock, INFINITE );
+ WaitForSingleObject(masterLock, INFINITE );
#endif
if ((button == Remote::NA_NONE) || (button == Remote::NA_UNKNOWN)) continue;
}
#ifndef WIN32
- pthread_mutex_unlock(&masterLock);
+ pthread_mutex_unlock(&masterLock);
#else
- ReleaseMutex(masterLock);
+ ReleaseMutex(masterLock);
#endif
}
#ifndef WIN32
- pthread_mutex_lock(&masterLock);
+ pthread_mutex_lock(&masterLock);
#else
- WaitForSingleObject(masterLock, INFINITE );
+ WaitForSingleObject(masterLock, INFINITE );
#endif
- MessageQueue::postMessage(m);
+ MessageQueue::postMessage(m);
#ifndef WIN32
- kill(mainPid, SIGURG);
- pthread_mutex_unlock(&masterLock);
+ kill(mainPid, SIGURG);
+ pthread_mutex_unlock(&masterLock);
#else
- //TODO: send Window Message
- ReleaseMutex(masterLock);
+ ((RemoteWin*)Remote::getInstance())->Signal();
+ ReleaseMutex(masterLock);
#endif
}
return false;
}
#else
- if (WaitForSingleObject(masterLock, INFINITE ) == WAIT_OBJECT_0)
- {
+ switch (WaitForSingleObject(masterLock, 0 ))
+ { //FIXME this is not "if not busy" check
+ case WAIT_OBJECT_0: //but with proper argument 0 this did not work
+ // case WAIT_ABANDONED:
MessageQueue::postMessage(m);
- //TODO: send Window Message
+ ((RemoteWin*)Remote::getInstance())->Signal();
ReleaseMutex(masterLock);
return true;
+
+ case WAIT_ABANDONED: return false;
+ case WAIT_TIMEOUT: return false;
}
- else
- {
return false;
- }
#endif
}
logger->log("Command", Log::DEBUG, "Switching to NTSC");
video->init(Video::NTSC);
}
- osd->init("/dev/stbgfx");
+ osd->init((char*)("/dev/stbgfx"));
// Put the wallpaper back
doWallpaper();
#ifndef DEFINES_H
#define DEFINES_H
+//#define NEW_DEMUXER //Switch for the new demuxer code
+//At the beginning the changed code will be switchable
+//in order to apply the changes also to the mvp code
+
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef unsigned int UINT;
#define SNPRINTF _snprintf
#define VSNPRINTF _vsnprintf
- #define STRCASECMP stricmp
+ #define STRCASECMP _stricmp
#define STRCASESTR StrStrI
#define STRTOULL _strtoui64
#define CLOSESOCKET closesocket
!audiostream.init(demuxMemoryA) ||
!(local_frame = (UCHAR *) malloc(0x10000)))
{
- // printf("failed to initialize demuxer\n");
+ Log::getInstance()->log("Demuxer", Log::CRIT, "Failed to initialize demuxer");
shutdown();
return 0;
}
+#ifdef NEW_DEMUXER
+ videostream.setDrainTarget(Video::getInstance());
+ audiostream.setDrainTarget(Audio::getInstance());
+#endif
}
reset();
else
arcnt = 0;
}
-
+#ifndef NEW_DEMUXER
int Demuxer::writeAudio(int fd)
{
return audiostream.drain(fd);
{
return videostream.drain(fd);
}
+#else
+int Demuxer::writeAudio(DrainTarget* dt)
+{
+ return audiostream.drain(dt);
+}
+
+int Demuxer::writeVideo(DrainTarget* dt)
+{
+ return videostream.drain(dt);
+}
+#endif
+
int Demuxer::scan(UCHAR *buf, int len)
{
#include "log.h"
#include "defines.h"
#include "callback.h"
+#include "draintarget.h"
+
+#include "audio.h"
+#include "video.h"
+
class Demuxer
{
void seek();
void setVideoStream(int id);
void setAudioStream(int id);
+#ifndef NEW_DEMUXER
int writeAudio(int fd);
int writeVideo(int fd);
+#else
+ int writeAudio(DrainTarget* dt);
+ int writeVideo(DrainTarget* dt);
+#endif
+
int scan(UCHAR* buf, int len);
int findVideoPTS(UCHAR* buf, int len, ULLONG* dest);
int put(UCHAR* buf, int len);
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "draintarget.h"
+DrainTarget::DrainTarget(){
+
+
+}
+DrainTarget::~DrainTarget(){
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DRAINTARGET_H
+#define DRAINTARGET_H
+
+#include "defines.h"
+#include <list>
+
+
+
+
+struct MediaPacket{
+ ULLONG recording_byte_pos; //position in recording
+ ULLONG pts;
+ ULONG pos_buffer; //position in stream buffer
+ ULONG length; //length of the packet
+ //The last to are only needed on windows, for memory reasons they can be excluded in mvp
+ long long presentation_time;/* in 100 ns units*/
+ bool synched;
+ bool disconti;
+};
+
+using namespace std;
+
+typedef list<MediaPacket> MediaPacketList;
+
+
+class DrainTarget {
+public:
+ DrainTarget();
+ virtual ~DrainTarget();
+ virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer,
+ UINT *samplepos)=0;
+
+/* This function behaviour should be:
+Try to deliver the Data from packet.pos_buffer+samplepos to packet.pos_buffer+packet.length,
+with considering the bufferwraparound according to buffersize.
+Then increasing samplepos, so that on the next call delivering can proceed. So if writebytes are
+writen samplepos=samplepos+writebytes!
+If samplepos>=packet.length is returned, the next packet can be used for the next call.*/
+
+ virtual long long SetStartOffset(long long curreftime, bool *rsync)=0;
+};
+
+
+
+
+#endif
\ No newline at end of file
#include <Ws2tcpip.h>
#endif
-#include <sys/types.h>
+#include <sys/types.h>
#ifndef WIN32
#include <sys/time.h>
#else
#include <sys/timeb.h>
#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "dssourcefilter.h"
+
+DsSourceFilter::DsSourceFilter():CBaseFilter("Vomp Source Filter",NULL,&crit_sec,_uuidof(this))
+{
+ //add audio pin
+ HRESULT res;
+ audiopin=new DsSourcePin(this,&crit_sec,&res,L"Vomp Audio Out",true);
+ videopin=new DsSourcePin(this,&crit_sec,&res,L"Vomp Video Out",false);
+
+}
+
+DsSourceFilter::~DsSourceFilter()
+{
+ if (audiopin) delete audiopin;
+ if (videopin) delete videopin;
+}
+
+int DsSourceFilter::GetPinCount()
+{
+ return 2; //audio and video
+}
+
+CBasePin *DsSourceFilter::GetPin(int n){
+ switch (n) {
+ case 0:
+ return audiopin;
+ case 1:
+ return videopin;
+ default:
+ return 0;
+ };
+}
+
+int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
+{
+ if (!audiopin || !IsActive()) {
+ return 0;
+ }
+ if (audiopin->GetDeliveryBuffer(ms,NULL,NULL,0)!=S_OK) {
+ return 0;
+ }
+ return 1;
+}
+
+int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
+{
+ if (!videopin || !IsActive()) {
+ return 0;
+ }
+ if (videopin->GetDeliveryBuffer(ms,NULL,NULL,0)!=S_OK) {
+ return 0;
+ }
+ return 1;
+}
+
+int DsSourceFilter::DeliverAudioMediaSample(IMediaSample* ms)
+{
+ if (!audiopin || !IsActive()) {
+ ms->Release();
+ return 0;
+ }
+ if (audiopin->Deliver(ms)!=S_OK) {
+ ms->Release();
+ return 0;
+ }
+ ms->Release();
+ return 1;
+
+}
+
+int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
+{
+ if (!videopin || !IsActive()) {
+ ms->Release();
+ return 0;
+ }
+ if (videopin->Deliver(ms)!=S_OK) {
+ ms->Release();
+ return 0;
+ }
+ ms->Release();
+ return 1;
+
+}
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DSSOURCEFILTER_H
+#define DSSOURCEFILTER_H
+
+
+#include "dssourcepin.h"
+
+[uuid("EB87AB22-7A95-49c3-8CCE-2F6D61A87009")]
+class DsSourceFilter: public CBaseFilter {
+public:
+ DsSourceFilter();
+ ~DsSourceFilter();
+ CCritSec* GetLock(){return &crit_sec;};
+ virtual int GetPinCount();
+ virtual CBasePin *GetPin(int n);
+ int getCurrentAudioMediaSample(IMediaSample** ms);
+ int DeliverAudioMediaSample(IMediaSample* ms);
+ int getCurrentVideoMediaSample(IMediaSample** ms);
+ int DeliverVideoMediaSample(IMediaSample* ms);
+protected:
+ CCritSec crit_sec;
+ DsSourcePin *audiopin;
+ DsSourcePin *videopin;
+
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include "dssourcepin.h"
+#include "dssourcefilter.h"
+#include <Dvdmedia.h>
+#include <mmreg.h>
+
+DsSourcePin::DsSourcePin(DsSourceFilter *pFilter,
+ CCritSec *pLock,HRESULT *phr,LPCWSTR pName,bool audio):
+CBaseOutputPin(NAME("dssourcepin"),pFilter,pLock,phr,pName)
+{
+ isaudiopin=audio;
+ m_pFilter=pFilter;
+
+}
+
+DsSourcePin::~DsSourcePin()
+{
+
+
+}
+
+HRESULT DsSourcePin::GetMediaType(int iPosition, CMediaType *pmt)
+{
+ HRESULT hr;
+ ASSERT(pmt);
+ pmt->InitMediaType();
+ if (isaudiopin){
+ if (iPosition==0) {
+ pmt->SetType(&MEDIATYPE_Audio);
+ MPEG1WAVEFORMAT wfe;
+ ZeroMemory(&wfe,sizeof(wfe));
+ wfe.wfx.cbSize=22;
+ wfe.wfx.nSamplesPerSec=48000;
+ wfe.wfx.nChannels=2;
+ wfe.wfx.nAvgBytesPerSec=32000;
+ wfe.wfx.nBlockAlign=768;
+ wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
+ wfe.fwHeadLayer=2;
+ wfe.dwHeadBitrate=256000;
+ wfe.fwHeadMode=ACM_MPEG_STEREO;
+ wfe.fwHeadModeExt=1;
+ wfe.wHeadEmphasis=1;
+ wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
+ pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO);
+ pmt->SetFormatType(&FORMAT_WaveFormatEx);
+ pmt->SetFormat((BYTE*)&wfe,sizeof(wfe));
+ pmt->SetSampleSize(0);
+ hr=S_OK;
+
+
+ } else {
+ hr=VFW_S_NO_MORE_ITEMS ;
+ }
+ } else {
+ if (iPosition == 0) {
+ pmt->SetType(&MEDIATYPE_Video);
+ hr=S_OK;
+ pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_VIDEO);
+ pmt->SetFormatType(&FORMAT_MPEG2Video);
+
+ MPEG2VIDEOINFO hdr;
+ ZeroMemory(&hdr,sizeof(hdr));
+ hdr.dwProfile=AM_MPEG2Profile_Main;
+ hdr.dwLevel=AM_MPEG2Level_Main;
+ hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);
+ hdr.hdr.bmiHeader.biWidth = 720;
+ hdr.hdr.bmiHeader.biHeight = 568;
+ pmt->SetFormat((BYTE*)&hdr,sizeof(hdr));
+ } else {
+ hr=VFW_S_NO_MORE_ITEMS;
+ }
+ }
+ return hr ;
+}
+
+// No description
+HRESULT DsSourcePin::CheckMediaType(const CMediaType *pmt)
+{
+ HRESULT res;
+ ASSERT (pmt);
+ if (isaudiopin) {
+ bool subtype=false;
+#if 0 /* For future demands ac3 */
+ subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
+#endif
+ subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
+ if (pmt->majortype==MEDIATYPE_Audio && subtype) {
+ res = S_OK ;
+ } else {
+ res = S_FALSE ;
+ }
+ } else {
+ if (pmt->majortype==MEDIATYPE_Video &&
+ pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO) {
+ res = S_OK ;
+ } else {
+ res = S_FALSE ;
+ }
+ }
+ return res;
+}
+
+HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){
+ HRESULT hr;
+ CAutoLock al(m_pFilter->GetLock());
+ CheckPointer(pa, E_POINTER);
+ CheckPointer(all_pp, E_POINTER);
+ if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
+ {
+ all_pp->cBuffers = 300;
+ all_pp->cbBuffer = 64*1024;
+ }
+ ALLOCATOR_PROPERTIES all_pp_cur;
+ hr =pa->SetProperties(all_pp,&all_pp_cur);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer)
+ {
+ return E_FAIL;
+ }
+
+ return S_OK;
+}
\ No newline at end of file
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef DSPINFILTER_H
+#define DSPINFILTER_H
+
+#include <streams.h>
+
+class DsSourceFilter;
+
+[uuid("17F931AB-9A87-4c65-B99E-84F5BC5F7B09")]
+class DsSourcePin: public CBaseOutputPin {
+public:
+ DsSourcePin(DsSourceFilter *pFilter,
+ CCritSec *pLock,HRESULT *phr,LPCWSTR pName,bool audio);
+ ~DsSourcePin();
+
+ virtual HRESULT DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp);
+protected:
+ virtual HRESULT CheckMediaType(const CMediaType *pmt);
+ virtual HRESULT GetMediaType(int iPosition, CMediaType *pmt);
+ bool isaudiopin;
+ DsSourceFilter *m_pFilter;
+
+
+
+};
+
+
+
+#endif
\ No newline at end of file
LedWin::LedWin()
{
- if (instance) return;
initted = 0;
}
_ftime(&tb);
struct tm* tms = localtime(&tb.time);
#endif
-
spaceLeft -= strftime(buffer, spaceLeft, "%H:%M:%S.", tms);
+#ifndef _MSC_VER
spaceLeft -= SNPRINTF(&buffer[150-spaceLeft], spaceLeft, "%06lu ", (unsigned long)tv.tv_usec);
-
+#else
+ spaceLeft -= SNPRINTF(&buffer[150-spaceLeft], spaceLeft, "%06lu ", (unsigned long)tb.millitm);
+#endif
char levelString[10];
if (level == CRAZY) strcpy(levelString, "[CRAZY] ");
#ifndef WIN32
#include <sys/time.h>
#else
- #include <winsock2.h>
#include <sys/timeb.h>
#endif
shutdown(1);
}
- success = osd->init("/dev/stbgfx");
+ success = osd->init((void*)("/dev/stbgfx"));
if (success)
{
logger->log("Core", Log::INFO, "OSD module initialised");
*/
#include "mtdwin.h"
+#include "video.h"
MtdWin::MtdWin()
{
- if (instance) return;
initted = 0;
}
short MtdWin::getPALorNTSC()
{
- return 0;
+ return Video::PAL; //Fixme!
}
MtdWin();
~MtdWin();
- int init(char* device);
- int shutdown();
+ virtual int init(char* device);
+ virtual int shutdown();
- short getPALorNTSC();
+virtual short getPALorNTSC();
private:
int initted;
virtual ~Osd();
static Osd* getInstance();
- virtual int init(char* device)=0;
+ virtual int init(void* device)=0;
virtual int shutdown()=0;
virtual int getFD()=0;
return fdOsd;
}
-int OsdMVP::init(char* device)
+int OsdMVP::init(void* device)
{
if (initted) return 0;
- fdOsd = open(device, O_RDWR);
+ fdOsd = open((char*)device, O_RDWR);
if (!fdOsd)
{
Log::getInstance()->log("OSD", Log::DEBUG, "Could not open OSD device!");
OsdMVP();
~OsdMVP();
- int init(char* device);
+ int init(void* device);
int shutdown();
int getFD();
*/
#include "osdwin.h"
+#include "mtd.h"
+#include "video.h"
+#include "surfacewin.h"
+
+//This is stuff for rendering the OSD
+
OsdWin::OsdWin()
{
- if (instance) return;
+ d3d=NULL;
+ d3ddevice=NULL;
+ d3dvb=NULL;
+ external_driving=false;
+ event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
+ d3dmutex = CreateMutex(NULL,FALSE,NULL);
+
}
OsdWin::~OsdWin()
{
if (initted) shutdown();
+ CloseHandle(event);
+ CloseHandle(d3dmutex);
}
int OsdWin::getFD()
return fdOsd;
}
-int OsdWin::init(char* device)
+int OsdWin::init(void* device)
{
if (initted) return 0;
+ Video* video = Video::getInstance();
+ //First Create Direct 3D Object
+ d3d=Direct3DCreate9(D3D_SDK_VERSION);
+ if (!d3d)
+ {
+ Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 object!");
+ return 0;
+ }
+ // then create the Device
+ D3DPRESENT_PARAMETERS d3dparas;
+ ZeroMemory(&d3dparas,sizeof(d3dparas));
+ d3dparas.BackBufferWidth=video->getScreenWidth();
+ d3dparas.BackBufferHeight=video->getScreenHeight();
+ d3dparas.Windowed=TRUE;
+ d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
+ if (d3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,*((HWND*) device),
+ D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dparas,&d3ddevice)!=D3D_OK) {
+ Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 device!");
+ return 0;
+ }
+ //TODO a render function and a device lost detection
+
+ if (!InitVertexBuffer()) {
+ Log::getInstance()->log("OSD", Log::DEBUG, "Could not create Direct3D9 vertex buf!");
+ return 0;
+ }
+
+ //Now we will create the Screen
+ screen = new SurfaceWin(Surface::SCREEN);
+ SetEvent(event);//Now all devices are ready
+ screen->create(video->getScreenWidth(), video->getScreenHeight());
+ screen->display();
initted = 1; // must set this here or create surface won't work
return 1;
}
+
+int OsdWin::InitVertexBuffer() {
+ Video* video = Video::getInstance();
+ FLOAT texx=((float)video->getScreenWidth())/1024.f;
+ FLOAT texy=((float)video->getScreenHeight())/1024.f;
+ D3DCOLOR osdcolor=D3DCOLOR_RGBA(255,255,255,255);
+ osdvertices[0].c=osdcolor;
+ osdvertices[0].x=0.f-0.5f;
+ osdvertices[0].y=0.f-0.5f;
+ osdvertices[0].z=0.5f;
+ osdvertices[0].rhw=1.f;
+ osdvertices[0].u=0.f;
+ osdvertices[0].v=0.f;
+ osdvertices[1].c=osdcolor;
+ osdvertices[1].x=((float)video->getScreenWidth())-0.5f;-0.5f;
+ osdvertices[1].y=0.f-0.5f;
+ osdvertices[1].z=0.5f;
+ osdvertices[1].u=texx;
+ osdvertices[1].v=0.f;
+ osdvertices[1].rhw=1.f;
+ osdvertices[2].c=osdcolor;
+ osdvertices[2].x=((float)video->getScreenWidth())-0.5f;
+ osdvertices[2].y=((float)video->getScreenHeight())-0.5f;
+ osdvertices[2].z=0.5f;
+ osdvertices[2].rhw=1.f;
+ osdvertices[2].u=texx;
+ osdvertices[2].v=texy;
+ osdvertices[3].c=osdcolor;
+ osdvertices[3].x=0.f-0.5f;
+ osdvertices[3].y=((float)video->getScreenHeight())-0.5f;
+ osdvertices[3].z=0;
+ osdvertices[3].rhw=1.f;
+ osdvertices[3].u=0.f;
+ osdvertices[3].v=texy;
+ if (d3dvb) {
+ d3dvb->Release();
+ d3dvb=NULL;
+ }
+ if (d3ddevice->CreateVertexBuffer(4*sizeof(OSDVERTEX),0,D3DFVF_OSDVERTEX,D3DPOOL_MANAGED,
+ &d3dvb,NULL)!=D3D_OK) {
+ return 0;
+ }
+ void *pvertex=NULL;
+ if (d3dvb->Lock(0,sizeof(osdvertices),&pvertex,0)!=D3D_OK) {
+ return 0;
+ }
+ memcpy(pvertex,osdvertices,sizeof(osdvertices));
+ d3dvb->Unlock();
+ return 1;
+}
+
int OsdWin::shutdown()
{
if (!initted) return 0;
initted = 0;
+ d3ddevice->Release();
+ d3d->Release();
+
return 1;
}
{
screen->screenShot(fileName);
}
+
+// This function is called from the WinMain function in order to get Screen updates
+void OsdWin::Render()
+{
+ if (!initted) return ;
+ if (external_driving) {
+ Sleep(5); //Sleep for 5 ms, in order to avoid blocking the other threads
+ } else {
+ InternalRendering();
+ }
+}
+
+
+void OsdWin::InternalRendering(){
+ WaitForSingleObject(event,INFINITE);
+ BeginPainting();
+ if (external_driving) {
+ //Copy video to Backbuffer
+ } else {
+ //Clear Background
+ d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
+ }
+ //Drawing the OSD
+ if (d3ddevice->BeginScene()==D3D_OK) {
+ d3ddevice->SetStreamSource(0,d3dvb,0,sizeof(OSDVERTEX));
+ d3ddevice->SetFVF(D3DFVF_OSDVERTEX);
+ d3ddevice->SetTexture(0,((SurfaceWin*)screen)->getD3dtexture());
+ //d3ddevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
+ d3ddevice->SetTextureStageState(0, D3DTSS_ALPHAOP,D3DTOP_MODULATE);
+ d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
+ d3ddevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
+ d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
+ d3ddevice->SetRenderState(D3DRS_LIGHTING,FALSE);
+
+
+ d3ddevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
+ d3ddevice->EndScene();
+ //Show it to the user!
+ if (d3ddevice->Present(NULL,NULL,NULL,NULL)==D3DERR_DEVICELOST){
+ EndPainting();
+ DoLost();
+ }
+ EndPainting();
+ }
+ if (!external_driving) {
+ Sleep(4);//The User can wait for 4 milliseconds to see his changes
+ }
+}
+
+void OsdWin::DoLost(){
+ Log::getInstance()->log("OSD", Log::DEBUG, "Direct3D Device Lost! Reobtaining...");
+ ResetEvent(event);
+ //First we free up all resources
+ Video* video = Video::getInstance();
+ ((SurfaceWin*)screen)->ReleaseSurface();
+ d3dvb->Release();
+ d3dvb=NULL;
+ D3DPRESENT_PARAMETERS d3dparas;
+ ZeroMemory(&d3dparas,sizeof(d3dparas));
+ d3dparas.BackBufferWidth=video->getScreenWidth();
+ d3dparas.BackBufferHeight=video->getScreenHeight();
+ d3dparas.Windowed=TRUE;
+ d3dparas.SwapEffect=D3DSWAPEFFECT_COPY;
+ if (d3ddevice->Reset(&d3dparas)!=D3D_OK){
+ return;
+ }
+ screen->create(video->getScreenWidth(), video->getScreenHeight());
+ screen->display();
+ InitVertexBuffer();
+ //Redraw Views, Chris could you add a member function to viewman, so that
+ // I can cause it to completely redraw the Views?
+ // Otherwise the OSD would be distorted after Device Lost
+ SetEvent(event);
+
+}
+LPDIRECT3DDEVICE9 OsdWin::getD3dDev() {
+ WaitForSingleObject(event,INFINITE);//We will only return if we are initted
+ return d3ddevice;
+}
+
+void OsdWin::BeginPainting() {//We synchronize calls to d3d between different threads
+ WaitForSingleObject(d3dmutex,INFINITE);
+}
+
+void OsdWin::EndPainting() {
+ ReleaseMutex(d3dmutex);
+}
#include "osd.h"
#include "defines.h"
#include "log.h"
+#include <winsock2.h>
+#include <d3d9.h>
+
+struct OSDVERTEX
+{
+ FLOAT x,y,z,rhw;
+ DWORD c;
+ FLOAT u,v;
+};
+
+#define D3DFVF_OSDVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE| D3DFVF_TEX1)
+
class OsdWin : public Osd
{
OsdWin();
~OsdWin();
- int init(char* device);
+ int init(void* device);
int shutdown();
int getFD();
void screenShot(char* fileName);
- private:
+ LPDIRECT3DDEVICE9 getD3dDev() ;
+ // This function is called from the WinMain function in order to get Screen updates
+ void Render();
+ void BeginPainting();
+ void EndPainting();
+private:
+ LPDIRECT3D9 d3d;
+ LPDIRECT3DDEVICE9 d3ddevice;
+ LPDIRECT3DVERTEXBUFFER9 d3dvb;
+ // This indicates, that currently a video is played, thus the osd updates are driven by the Directshow Filtersystem
+ bool external_driving;
+ HANDLE d3dmutex;
+ void InternalRendering();
+ void DoLost();
+ int InitVertexBuffer();
+ OSDVERTEX osdvertices[4];
+ HANDLE event;
};
#endif
streamLength = 0;
feedPosition = 0;
feedMode = MODE_NORMAL;
+ videoStartup = false;
isRecording = tIsRecording;
lastRescan = 0;
startTS = 0;
{
blockSize = 20000;
startupBlockSize = 60000;
+ video->turnVideoOff();
}
else
{
blockSize = 100000;
startupBlockSize = 250000;
+ video->turnVideoOn();
}
}
shutdown();
return 0;
}
-
+#ifndef NEW_DEMUXER
vfeed.init(video->getFD());
afeed.init(audio->getFD());
+#else
+ vfeed.init(video);
+ afeed.init(audio);
+#endif
video->stop();
video->blank();
demuxer.reset();
// ------------------------ This one works, but doesn't allow any pre-buffering.
+ videoStartup = true;
threadStart();
- vfeed.start();
afeed.start();
- audio->play();
- video->play();
video->sync();
audio->sync();
+ audio->play();
+ video->pause();
+
- resyncVideo();
// ------------------------ This one doesn't work, but it should, and would allow for prebuffering.
-/*
- threadStart();
-// MILLISLEEP(1000);
-
- vfeed.start();
- afeed.start();
- video->play();
- audio->play();
- audio->sync();
- video->sync();
- resyncVideo();
-*/
// ------------------------------------------------------------------------------------------------
logger->log("Player", Log::DEBUG, "Player has received length of %llu", streamLength);
}
-void Player::skipForward(int seconds)
+void Player::restartAt(ULLONG timecode)
{
- logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
-
if (paused) togglePause();
+ if (ffwd) toggleFastForward();
- ULONG wantedFrameNumber = video->timecodeToFrameNumber(getPositionTS() + (seconds * 90000));
+ ULONG wantedFrameNumber = video->timecodeToFrameNumber(timecode);
ULLONG newPosition = VDR::getInstance()->positionFromFrameNumber(wantedFrameNumber);
if (!VDR::getInstance()->isConnected()) { doConnectionLost(); return; }
logger->log("Player", Log::DEBUG, "wantedframe %i feedpos %llu goto %llu", wantedFrameNumber, feedPosition, newPosition);
video->stop();
video->reset();
audio->reset();
- audio->doMuting(); // ???
demuxer.flush();
feedPosition = newPosition;
- vfeed.start();
+ videoStartup = true;
afeed.start();
threadStart();
audio->play();
- video->play();
video->sync();
audio->sync();
audio->systemMuteOff();
audio->doMuting();
- ffwd = false;
fbwd = false;
- paused = false;
+}
- resyncVideo();
+void Player::skipForward(int seconds)
+{
+ logger->log("Player", Log::DEBUG, "SKIP FORWARD %i SECONDS", seconds);
+ restartAt(getPositionTS() + (seconds * 90000));
}
void Player::skipBackward(int seconds)
{
logger->log("Player", Log::DEBUG, "SKIP BACKWARD %i SECONDS", seconds);
-
- if (paused) togglePause();
-
- ULLONG newPosition = 0;
-
long long newTimeCode = getPositionTS() - (seconds * 90000);
- if (newTimeCode > 0)
- {
- ULONG wantedFrameNumber = video->timecodeToFrameNumber((ULLONG)newTimeCode);
- newPosition = VDR::getInstance()->positionFromFrameNumber(wantedFrameNumber);
- if (!VDR::getInstance()->isConnected()) { doConnectionLost(); return; }
- logger->log("Player", Log::DEBUG, "wantedframe %i feedpos %llu goto %llu", wantedFrameNumber, feedPosition, newPosition);
- }
-
- vfeed.stop();
- afeed.stop();
- threadStop();
- video->stop();
- audio->stop();
- video->reset();
- audio->reset();
- audio->doMuting(); // ???
- demuxer.flush();
- feedPosition = newPosition;
- vfeed.start();
- afeed.start();
- threadStart();
- audio->play();
- video->play();
- video->sync();
- audio->sync();
- audio->systemMuteOff();
- audio->doMuting();
- ffwd = false;
- fbwd = false;
- paused = false;
+ if (newTimeCode < 0) newTimeCode = 0;
+ restartAt(newTimeCode);
+}
- resyncVideo();
+void Player::jumpToPercent(int percent)
+{
+ logger->log("Player", Log::DEBUG, "JUMP TO %i%%", percent);
+ ULLONG newTimeCode = (ULLONG)(getEndTS() * ((float)percent / 100));
+ restartAt(newTimeCode);
}
void Player::toggleFastForward()
if (ffwd)
{
ffwd = false;
-// video->unFastForward();
-
-
+ threadStop();
vfeed.stop();
afeed.stop();
- threadStop();
video->stop();
audio->stop();
video->reset();
audio->reset();
demuxer.flush();
-// demuxer.seek();
- vfeed.start();
+
+ videoStartup = true;
afeed.enable();
afeed.start();
threadStart();
- video->play();
- audio->play();
- video->sync();
- audio->sync();
-
- audio->systemMuteOff();
-
- resyncVideo();
-/*
- demuxer.flushAudio();
- audio->reset();
- afeed.enable();
- //video->reset();
audio->play();
- video->play();
video->sync();
audio->sync();
audio->systemMuteOff();
-*/
+ audio->doMuting();
+ fbwd = false;
}
else
{
}
}
-void Player::jumpToPercent(int percent)
-{
- if (paused) togglePause();
- if (ffwd) toggleFastForward();
-
- vfeed.stop();
- afeed.stop();
- threadStop();
- video->stop();
- audio->stop();
- video->reset();
- audio->reset();
- demuxer.flush();
- demuxer.seek();
- feedPosition = streamLength * percent / 100;
- vfeed.start();
- afeed.start();
- threadStart();
- audio->play();
- video->play();
- video->sync();
- audio->sync();
-
- resyncVideo();
-}
-
ULLONG Player::getPositionTS()
{
if (startup) return 0ULL;
}
else
{
+ if (videoStartup)
+ {
+ videoStartup = false;
+ logger->log("Player", Log::DEBUG, "Starting VFeed");
+ MILLISLEEP(500);
+ logger->log("Player", Log::DEBUG, "Starting VFeed2");
+ video->reset();
+ video->play();
+ video->sync();
+ vfeed.start();
+ }
+
threadSignalNoLock();
}
}
-
void Player::doConnectionLost()
{
Message* m = new Message();
void Player::test1()
{
logger->log("Player", Log::DEBUG, "PLAYER TEST 1");
+ video->setAspectRatio(Video::ASPECT4X3);
}
void Player::test2()
{
logger->log("Player", Log::DEBUG, "PLAYER TEST 2");
+ video->setAspectRatio(Video::ASPECT16X9);
}
#endif
void setStartTS(UINT dataInBuffer);
void setEndTS();
void doConnectionLost();
+ void restartAt(ULLONG timeCode);
int initted;
MessageQueue* commandMessageQueue;
int startup;
VFeed vfeed;
AFeed afeed;
+ bool videoStartup;
ULLONG startTS;
ULLONG endTS;
#include "remotewin.h"
+
RemoteWin::RemoteWin()
{
- if (instance) return;
initted = 0;
+ curevent=NA_NONE;
+ signal=false;
}
RemoteWin::~RemoteWin()
{
if (initted) return 0;
initted = 1;
+ event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
+
return 1;
}
int RemoteWin::shutdown()
{
if (!initted) return 0;
+ CloseHandle(event);
initted = 0;
return 1;
}
how = 2 - continue wait
how = 3 - no wait
*/
+ DWORD wait;
+ if (curevent!=NA_NONE) {
+ UCHAR temp=curevent;
+ curevent=NA_NONE;
+ return temp;
+ }
+ if (waitType==3) {
+ return NA_NONE;
+ }
+ if (waitType==0) {
+ wait=INFINITE;
+ } else { //We do not distingish between 2 and 3
+ wait=1000;
+
+ }
+ WaitForSingleObject(event,wait);
+ ResetEvent(event);
+ if (curevent==NA_NONE) {
+ if (signal) {
+ signal=false;
+ return NA_SIGNAL; //Since we have no signals on windows, we simulate this
+ } else {
+ return NA_NONE;
+ }
+ }
+ UCHAR temp2=curevent;
+ curevent=NA_NONE;
+ return temp2;
- return NA_UNKNOWN;
}
void RemoteWin::clearBuffer()
{
}
+
+int RemoteWin::ReceiveButtonVK(UINT button) {
+ UCHAR pb=NA_NONE;
+ //should we use a translation table ? No APPCOMMAND iS DWORD!
+ switch (button) { //Processing VK_Messages
+ case VK_DOWN:
+ pb=DOWN; break;
+ case VK_RETURN:
+ case VK_SPACE:
+ pb=OK;break;
+ case VK_LEFT:
+ pb=LEFT;break;
+ case '9':
+ case VK_NUMPAD9:
+ pb=NINE;break;
+ case '8':
+ case VK_NUMPAD8:
+ pb=EIGHT;break;
+ case '7':
+ case VK_NUMPAD7:
+ pb=SEVEN;break;
+ case '6':
+ case VK_NUMPAD6:
+ pb=SIX;break;
+ case '5':
+ case VK_NUMPAD5:
+ pb=FIVE;break;
+ case '4':
+ case VK_NUMPAD4:
+ pb=FOUR;break;
+ case '3':
+ case VK_NUMPAD3:
+ pb=THREE;break;
+ case '2':
+ case VK_NUMPAD2:
+ pb=TWO;break;
+ case '1':
+ case VK_NUMPAD1:
+ pb=ONE;break;
+ case '0':
+ case VK_NUMPAD0:
+ pb=ZERO;break;
+ case VK_RIGHT:
+ pb=RIGHT;break;
+ case VK_UP:
+ pb=UP;break;
+ case VK_MULTIPLY:
+ pb=STAR;break;
+ case 'J'://j for JUMP TO instead of go to
+ pb=GO;break;
+ case VK_ESCAPE:
+ pb=POWER;break;
+ case VK_BACK:
+ pb=BACK;break;
+ case 'M':
+ pb=MENU;break;
+ case 'R':
+ pb=RED;break;
+ case 'G':
+ pb=GREEN;break;
+ case 'Y':
+ pb=YELLOW;break;
+ case 'B':
+ pb=BLUE; break;
+
+
+ }; //All other commands are process via APPCOMMAND_MESSAGES
+ if (pb==NA_NONE) return 0;
+ curevent=pb;
+ //PulseEvent(event);
+ SetEvent(event);
+ return 1;
+}
+
+int RemoteWin::ReceiveButtonAP(UINT button) {
+ UCHAR pb=NA_NONE;
+ //should we use a translation table ? No APPCOMMAND iS DWORD!
+ switch (button) { //Processing VK_Messages
+ case APPCOMMAND_MEDIA_CHANNEL_DOWN:
+ pb=CHANNELDOWN;break;
+ case APPCOMMAND_MEDIA_CHANNEL_UP:
+ pb=CHANNELUP;break;
+ case APPCOMMAND_MEDIA_FAST_FORWARD:
+ pb=FORWARD;break;
+ case APPCOMMAND_VOLUME_MUTE:
+ pb=MUTE;break;
+ case APPCOMMAND_MEDIA_PAUSE:
+ pb=PAUSE;break;
+ case APPCOMMAND_MEDIA_PLAY:
+ pb=PLAY;break;
+ case APPCOMMAND_MEDIA_RECORD:
+ pb=RECORD;break;
+ case APPCOMMAND_MEDIA_PREVIOUSTRACK:
+ pb=SKIPBACK;break;
+ case APPCOMMAND_MEDIA_REWIND:
+ pb=REVERSE;break;
+ case APPCOMMAND_MEDIA_NEXTTRACK:
+ pb=SKIPFORWARD;break;
+ case APPCOMMAND_MEDIA_STOP:
+ pb=STOP;break;
+ case APPCOMMAND_VOLUME_DOWN:
+ pb=VOLUMEDOWN;break;
+ case APPCOMMAND_VOLUME_UP:
+ pb=VOLUMEUP;break;
+ };
+ if (pb==NA_NONE) return 0;
+ curevent=pb;
+ //PulseEvent(event);
+ SetEvent(event);
+ return 1;
+}
+
+void RemoteWin::Signal() {
+ signal=true;
+ //PulseEvent(event);
+ SetEvent(event);
+}
#include "log.h"
#include "remote.h"
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <windowsx.h>
+
+
+
class RemoteWin : public Remote
{
public:
int getDevice();
UCHAR getButtonPress(int how);
void clearBuffer();
+ void Signal();
+ int ReceiveButtonVK(UINT button);//Windows Message from WND_PROC
+ int ReceiveButtonAP(UINT button);
private:
int initted;
+ bool signal;
+ UCHAR curevent;
+ HANDLE event;
};
#endif
Stream::Stream()
{
initted = 0;
+#ifdef NEW_DEMUXER
+ cur_packet_pos=0;
+ draintarget=NULL;
+#endif
}
Stream::~Stream()
void Stream::shutdown()
{
- if (initted) {
- free(outbuf);
- }
+ if (initted) free(outbuf);
initted = 0;
}
void Stream::flush()
{
+#ifdef NEW_DEMUXER
+ mediapackets.clear();
+#endif
bufferHead = 0;
bufferTail = 0;
bufferMark = -1;
}
+#ifndef NEW_DEMUXER
int Stream::put(UCHAR* inbuf, int len)
{
int ret = 0;
}
return ret;
}
-
+#else
+int Stream::put(UCHAR* inbuf, int len)
+{
+ int ret = 0;
+ int tail = bufferTail;
+ int head = bufferHead;
+ if (tail == 0) tail = bufferSize;
+
+ if (!draintarget) return 0;
+ MediaPacket newPacket;
+ newPacket.length=len;
+ newPacket.pos_buffer=0;
+ newPacket.recording_byte_pos=0;
+ newPacket.synched=false;
+ newPacket.disconti=false;
+ newPacket.pts=0;
+ newPacket.presentation_time=0;
+ //Extract the pts...
+ if ((inbuf[7] & 0x80) && len>14 ) {
+ newPacket.synched=true;
+ newPacket.pts=((ULLONG)(inbuf[9] & 0x0E) << 29 ) |
+ ( (ULLONG)(inbuf[10]) << 22 ) |
+ ( (ULLONG)(inbuf[11] & 0xFE) << 14 ) |
+ ( (ULLONG)(inbuf[12]) << 7 ) |
+ ( (ULLONG)(inbuf[13] & 0xFE) >> 1 );
+ //ok we have the pts now convert it to a continously time code in 100ns units
+ newPacket.presentation_time=(ULLONG)(newPacket.pts*10000LL/90LL);
+ newPacket.presentation_time-=draintarget->SetStartOffset(newPacket.presentation_time,&newPacket.disconti);
+ }
+
+ if (head < tail)
+ {
+ // The free space is in one continuous chunk.
+ if (len < tail - head)
+ {
+ memcpy(outbuf + head, inbuf, len);
+ bufferHead += len;
+ ret = len;
+ newPacket.pos_buffer=head;
+ mediapackets.push_front(newPacket);
+ }
+ }
+ else if (len <= bufferSize - head)
+ {
+ // There is enough space above the Head.
+ memcpy(outbuf + head, inbuf, len);
+ if (head + len == bufferSize)
+ bufferHead = 0;
+ else
+ bufferHead += len;
+
+ newPacket.pos_buffer=head;
+ mediapackets.push_front(newPacket);
+
+ ret = len;
+ }
+ else if (len < tail)
+ {
+ bufferMark = head;
+ memcpy(outbuf, inbuf, len);
+ bufferHead = len;
+ ret = len;
+ newPacket.pos_buffer=0;
+ mediapackets.push_front(newPacket);
+ }
+ return ret;
+}
+#endif
+
+#ifndef NEW_DEMUXER
+
int Stream::drain(int fd)
{
int ret = 0;
int tail = bufferTail;
int mark = bufferMark;
int written;
-#ifndef WIN32
+
if (mark == -1 && tail > head) mark = bufferSize;
if (mark >= 0)
{
// Drain up to the marker.
+#ifndef WIN32
written = write(fd, outbuf + tail, (mark - tail));
+#else
+ written=mark-tail;
+ MILLISLEEP(1);
+#endif
if (written < 0) return ret;
ret += written;
if (written == (mark - tail))
}
if (tail == head) return ret; // Empty
-
+#ifndef WIN32
written = write(fd, outbuf + tail, (head - tail));
+#else
+ written=(head - tail);
+ MILLISLEEP(1);
+#endif
if (written < 0) return ret;
ret += written;
bufferTail = tail + written;
return ret;
- #else
- return 0; //to do!
- #endif //Again this have to betransformed into abstract base class and derived class
+}
+#else
+int Stream::drain(DrainTarget* dt)
+{
+ int ret = 0;
+ int written=1;
+ draintarget=dt;
+
+
+ if (mediapackets.empty()) {
+ return 0;
+ }
+ // using mediapackets, may be this is slower but it is more flexible
+ // while (!mediapackets.empty() && written) {
+
+ int head = bufferHead;
+ int tail = bufferTail;
+ int mark = bufferMark;
+ if (mark == -1 && tail > head) mark = bufferSize;
+ MediaPacket cur_mp=mediapackets.back();
+ written=0;
+ written=dt->DeliverMediaSample(cur_mp,outbuf,&cur_packet_pos);
+
+ ret+=written;
+
+ if (cur_packet_pos==cur_mp.length) {
+ cur_packet_pos=0;
+ mediapackets.pop_back();
+ if ((int)(tail+cur_mp.length) < mark) {
+ bufferTail=tail+cur_mp.length;
+ } else {
+ bufferTail=0;
+ bufferMark=-1;
+ }
+
+ }
+
+ return ret;
}
+
+#endif
#endif
#include <memory.h>
#include "defines.h"
+#include "draintarget.h"
+
+
class Stream
{
void shutdown();
void flush();
int put(UCHAR* inbuf, int len);
+#ifndef NEW_DEMUXER
int drain(int fd);
+#else
+ int drain(DrainTarget* fd);
+ void setDrainTarget(DrainTarget *dt) {draintarget=dt;};
+#endif
private:
+#ifdef NEW_DEMUXER
+ MediaPacketList mediapackets;
+ UINT cur_packet_pos;
+ DrainTarget* draintarget;
+#endif
int initted;
UCHAR* outbuf;
*/
#include "surfacewin.h"
-#include "osd.h"
+#include "osdwin.h"
+#include <d3dx9tex.h>
SurfaceWin::SurfaceWin(int id)
: Surface(id)
{
+ d3dtexture=NULL;
+ d3dsurface=NULL;
+ sheight=swidth=0;
+ event = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
}
SurfaceWin::~SurfaceWin()
{
+ if (d3dsurface) d3dsurface->Release();
+ if (d3dtexture) d3dtexture->Release();
+ CloseHandle(event);
}
int SurfaceWin::create(UINT width, UINT height)
{
- return 0;
+ LPDIRECT3DDEVICE9 d3ddev=((OsdWin*)(Osd::getInstance()))->getD3dDev();
+ while (true) {
+ if (screen==this) {
+ if (d3ddev->CreateTexture(1024,1024,0,0,D3DFMT_A8R8G8B8,
+ // Does every adapter with alpha blending support this?
+ D3DPOOL_DEFAULT,&d3dtexture ,NULL)!=D3D_OK) {
+ MILLISLEEP(50);//wait maybe next time it will work
+ continue;
+ }
+ if (d3dtexture->GetSurfaceLevel(0,&d3dsurface)!=D3D_OK) {
+ d3dtexture->Release();
+ d3dtexture=NULL;
+ MILLISLEEP(50);
+ continue;
+ }
+ } else {
+ HRESULT hres;
+ if (hres=d3ddev->CreateOffscreenPlainSurface(width,height,D3DFMT_A8R8G8B8,
+ D3DPOOL_SYSTEMMEM,&d3dsurface,NULL)!=D3D_OK) {
+ MILLISLEEP(50);//wait maybe next time it will work
+ continue;
+ }
+
+ }
+ sheight=height;
+ swidth=width;
+ /* If someone does high performance Animations on the OSD, we have to change the types
+ of surface in order to address these performance issues, if we have only very few updates
+ per second this would be fast enough !*/
+ break;
+ }
+ SetEvent(event);
+ return 1;
}
void SurfaceWin::display()
int SurfaceWin::fillblt(int x, int y, int width, int height, unsigned int c)
{
+ WaitForSingleObject(event,INFINITE); //since this might be called before surface
+ //allocation we will wait in this case, hopefully without deadlocks
+ OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+
+ if (!d3dsurface) {
+ return 0; //why does this happen
+ }
+
+ LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
+
+ if (screen==this) {
+ //This should not happen!
+ return 0;
+
+ } else {
+ osd->BeginPainting();
+ D3DLOCKED_RECT lockrect;
+ int cx,cy,cwidth,cheight;
+ cx=min(max(x,0),swidth);
+ cy=min(max(y,0),sheight);
+ cwidth=min(width,swidth-x);
+ cheight=min(height,sheight-y);
+ RECT rect={cx,cy,cwidth,cheight};
+
+ if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
+ return 0;
+ }
+ unsigned int line;
+ unsigned int column;
+ for (line=0;line<cheight;line++) {
+ unsigned int*row=((unsigned int*)(((char*)lockrect.pBits)+lockrect.Pitch*line));
+ for (column=0;column<cwidth;column++) {
+ row[column]=c;
+ }
+ }
+
+ if (d3dsurface->UnlockRect()!=D3D_OK) {
+ osd->EndPainting();
+ return 0;
+ }
+ osd->EndPainting();
+ }
+
return 0;
}
void SurfaceWin::drawPixel(int x, int y, unsigned int c)
{
+ //FixMe: locking for every single Pixel will be painfully slow
+ WaitForSingleObject(event,INFINITE); //since this might be called before surface
+ //allocation we will wait in this case, hopefully without deadlocks
+ if (!d3dsurface) {
+ return; //why does this happen
+ }
+ OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+ LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
+ if (x>swidth || y>sheight) return; //do not draw outside the surface
+ if (screen==this) {
+ //This should not happen!
+ return ;
+
+ } else {
+ osd->BeginPainting();
+ D3DLOCKED_RECT lockrect;
+ RECT rect={x,y,x+1,y+1};
+ if (d3dsurface->LockRect(&lockrect,&rect,D3DLOCK_DISCARD)!=D3D_OK) {
+ osd->EndPainting();
+ return ;
+ }
+ unsigned int*row=(unsigned int*)(((char*)lockrect.pBits));
+ row[0]=c;
+ if (d3dsurface->UnlockRect()!=D3D_OK) {
+ osd->EndPainting();
+ return ;
+ }
+ osd->EndPainting();
+ }
+
}
void SurfaceWin::drawHorzLine(int x1, int x2, int y, unsigned int c)
{
+ fillblt(x1, y, x2-x1, 1, c);
}
void SurfaceWin::drawVertLine(int x, int y1, int y2, unsigned int c)
{
+ fillblt(x, y1, 1, y2-y1, c);
}
int SurfaceWin::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
{
+ WaitForSingleObject(event,INFINITE); //since this might be called before surface
+ //allocation we will wait in this case, hopefully without deadlocks
+ if (!d3dsurface) {
+ return 0; //why does this happen
+ }
+ OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+ LPDIRECT3DDEVICE9 d3ddev=osd->getD3dDev();
+ LPDIRECT3DSURFACE9 screensurface=((SurfaceWin*)screen)->getD3dsurface();
+ if (!screensurface) return 0;
+ RECT sourcerect={sx,sy,sx+w,sy+h};
+ POINT destpoint={dx,dy};
+ osd->BeginPainting();
+ if (d3ddev->UpdateSurface(d3dsurface,&sourcerect,screensurface,&destpoint)!=D3D_OK) {
+ Log::getInstance()->log("Surface", Log::DEBUG, "Could not update to Screen!");
+ osd->EndPainting();
+ return 0;
+ }
+ osd->EndPainting();
return 0;
}
int SurfaceWin::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
{
+ //I don't see code using this function, so I skip it, since it is a MVP specific interface
return 0;
}
void SurfaceWin::screenShot(char* fileName)
{
+ //Isn't this for debugging only, so I won't implement it yet
}
void SurfaceWin::readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b)
{
+ //Isn't this for debugging only, so I won't implement it yet
+}
+void SurfaceWin::ReleaseSurface()
+{
+ ResetEvent(event);
+ LPDIRECT3DSURFACE9 temp_surf=d3dsurface;
+ LPDIRECT3DTEXTURE9 temp_text=d3dtexture;
+ d3dsurface=NULL;
+ d3dtexture=NULL;
+ sheight=swidth=0;
+ if (temp_surf) temp_surf->Release();
+ if (temp_text) temp_text->Release();
+}
+
+void SurfaceWin::drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height){
+ WaitForSingleObject(event,INFINITE); //since this might be called before surface
+ //allocation we will wait in this case, hopefully without deadlocks
+ if (!d3dsurface) {
+ return ; //why does this happen
+ }
+ OsdWin* osd=((OsdWin*)(Osd::getInstance()));
+
+
+ D3DXIMAGE_INFO image_inf;
+ osd->BeginPainting();
+ D3DXGetImageInfoFromFile(fileName,&image_inf);
+ RECT dest_rec={x,y,x+image_inf.Width,
+ y+image_inf.Height};
+ if (D3DXLoadSurfaceFromFile(
+ d3dsurface,
+ NULL,
+ &dest_rec,
+ fileName,
+ NULL,
+ D3DX_FILTER_NONE,
+ 0,
+ &image_inf)!=D3D_OK) {
+ Log::getInstance()->log("Surface", Log::DEBUG, "Could not open jpeg!");
+
+ }
+ osd->EndPainting();
+ *width=image_inf.Width;
+ *height=image_inf.Height;
+
}
#include "defines.h"
#include "log.h"
#include "surface.h"
+#include <winsock2.h>
+#include <d3d9.h>
class SurfaceWin : public Surface
{
int updateToScreen(int sx, int sy, int w, int h, int dx, int dy);
void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b);
void screenShot(char* fileName);
-
+ void ReleaseSurface();
int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy);
-
+ void drawJpeg(char *fileName,DWORD x, DWORD y,DWORD *width, DWORD *height);
+ LPDIRECT3DSURFACE9 getD3dsurface() {WaitForSingleObject(event,INFINITE);
+ return d3dsurface;};
+ LPDIRECT3DTEXTURE9 getD3dtexture() {return d3dtexture;};
private:
+ LPDIRECT3DSURFACE9 d3dsurface;
+ LPDIRECT3DTEXTURE9 d3dtexture;
+ UINT sheight,swidth;
+ HANDLE event;
};
#endif
*/
#include "tcp.h"
+#ifdef WIN32
+#include <Iphlpapi.h>
+#endif
TCP::TCP()
{
memcpy(dest, ifr.ifr_hwaddr.sa_data, 6);
#else
//TODO: Get MAC Address for windows
- memcpy(dest, "ABCDEF", 6);
+ PIP_ADAPTER_INFO daptinfo=NULL;
+ DWORD size=0;
+ GetAdaptersInfo(daptinfo,&size);
+ daptinfo=(PIP_ADAPTER_INFO)new char[size+1];
+ memcpy(dest,"ABCDEF", 6);//Dummy Address
+ sockaddr_in sock_address;
+ int sockname_len=sizeof(sock_address);
+ getsockname(sock,(sockaddr*)&sock_address,&sockname_len);
+ ULONG sockip=sock_address.sin_addr.s_addr;
+ if (GetAdaptersInfo(daptinfo,&size)==ERROR_SUCCESS)
+ {
+ PIP_ADAPTER_INFO daptinfo_it=daptinfo;
+ while (daptinfo_it!=NULL)
+ {
+ ULONG ipaddress=inet_addr(daptinfo_it->IpAddressList.IpAddress.String);
+ if (ipaddress==sockip)
+ { //Is it our MAC?
+ memcpy(dest,daptinfo_it->Address, 6);
+ break;
+ }
+ daptinfo_it=daptinfo_it->Next;
+ if (daptinfo_it==daptinfo) break;
+ }
+ }
+ else
+ {
+ // Marten?
+ }
+
+ delete [] daptinfo;
#endif
}
int ThreadWin::threadStart()
{
- threadCond = CreateEvent(NULL,FALSE,FALSE,NULL);
+ threadCond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL);
if (threadCond == NULL) return 0;
threadCondMutex = CreateMutex(NULL,FALSE,NULL);
if (threadCondMutex == NULL)
void ThreadWin::threadCancel()
{
threadActive = 0;
- TerminateThread(pthread, 0);
+ //TerminateThread(pthread, 0);
+ threadSignalNoLock();
WaitForSingleObject(pthread, INFINITE);
this->threadPostStopCleanup();
}
void ThreadWin::threadSignal()
{
WaitForSingleObject(threadCondMutex, INFINITE);
- PulseEvent(threadCond);
+ // PulseEvent(threadCond);
+ SetEvent(threadCond);
ReleaseMutex(threadCondMutex);
}
void ThreadWin::threadSignalNoLock()
{
- PulseEvent(threadCond);
+// PulseEvent(threadCond);
+ SetEvent(threadCond);
}
void ThreadWin::threadWaitForSignal()
{
+ threadUnlock();
WaitForSingleObject(threadCond,INFINITE);
+ ResetEvent(threadCond);
+ threadLock();
}
void ThreadWin::threadWaitForSignalTimed(struct timespec* ts)
{
+ threadUnlock();
HANDLE handles[2] ={threadCond, NULL};
LARGE_INTEGER duration;
- duration.QuadPart=ts->tv_sec*1000*1000*10+ts->tv_nsec/100;
-
+ duration.QuadPart=(ts->tv_sec*1000*1000*10+ts->tv_nsec/100)+WINDOWS_TIME_BASE_OFFSET;
handles[1]=CreateWaitableTimer(NULL,TRUE,NULL);
SetWaitableTimer(handles[1], &duration, 0, NULL, NULL, 0);
WaitForMultipleObjects(2,handles,FALSE,INFINITE);
+ ResetEvent(threadCond);
CloseHandle(handles[1]);
+ threadLock();
}
void ThreadWin::threadSetKillable()
#ifndef THREADWIN_H
#define THREADWIN_H
-#define _WIN32_WINNT 0x400
+
+#define _WIN32_WINNT 0x501
#include <winsock2.h>
#include <windows.h>
typedef struct timespec
long tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
} timespec;
+#define WINDOWS_TIME_BASE_OFFSET 116444736000000000
#include "thread.h"
__int64 test;\r
GetSystemTime(&systime);\r
SystemTimeToFileTime(&systime,(FILETIME*)&filetime);\r
- currentTime.tv_sec=filetime/(10*1000*1000);\r
- currentTime.tv_nsec=(filetime%(10*1000*1000))*100;\r
+ currentTime.tv_sec=(filetime-WINDOWS_TIME_BASE_OFFSET)/(10*1000*1000);\r
+ //#error "Hier gibt was zu tun!"\r
+ currentTime.tv_nsec=((filetime-WINDOWS_TIME_BASE_OFFSET)%(10*1000*1000))*100;\r
#endif\r
\r
long int requestedTime;\r
\r
// Check for reset..\r
// This can be caused by an addition or deletion to the list\r
- if (resetThreadFlag) continue;\r
+ if (resetThreadFlag || (nextTimer == NULL)) continue;\r
\r
// timer ran out\r
\r
int length = strlen(event->title); // calculate length of programme title string\r
char* title = new char[length + 15]; // create string to hold start time, end time and programme title\r
btime = localtime((time_t*)&event->time); //get programme start time\r
- strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -\r
+#ifndef _MSC_VER
+ strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -
+#else
+ strftime(timeString, 9, "%H:%M - ", btime); // and format it as hh:mm -
+#endif
strcpy(title, timeString); // put it in our buffer\r
t = event->time + event->duration; //get programme end time\r
btime = localtime(&t);\r
- strftime(timeString, 7, "%0H:%0M ", btime); // and format it as hh:mm -\r
+#ifndef _MSC_VER
+ strftime(timeString, 7, "%0H:%0M ", btime); // and format it as hh:mm -
+#else
+ strftime(timeString, 7, "%H:%M ", btime); // and format it as hh:mm -
+#endif
strcat(title, timeString); // put it in our buffer\r
strcat(title, event->title); // then add the programme title\r
progTitle.setText(title); // sput this sring in our text box\r
struct tm* btime;
char timeString[10];
btime = localtime((time_t*)&event->time);
+#ifndef _MSC_VER
strftime(timeString, 9, "%0H:%0M - ", btime); // and format it as hh:mm -
+#else
+ strftime(timeString, 9, "%H:%M - ", btime); // and format it as hh:mm -
+#endif
strcpy(fullString, timeString); // put it in our buffer
t = event->time + event->duration; //get programme end time
btime = localtime(&t);
+#ifndef _MSC_VER
strftime(timeString, 9, "%0H:%0M", btime); // and format it as hh:mm -
+#else
+ strftime(timeString, 9, "%H:%M", btime); // and format it as hh:mm -
+#endif
+
strcat(fullString, timeString); // put it in our buffer
drawText(fullString, 10, 40 + (3 * surface->getFontHeight()), Colour::LIGHTTEXT);
{
}
+#ifndef NEW_DEMUXER
int VFeed::init(int tfd)
{
fd = tfd;
return 1;
}
+#else
+int VFeed::init(DrainTarget* tdt)
+{
+ dt = tdt;
+ return 1;
+}
+#endif
int VFeed::shutdown()
{
while(1)
{
+#ifndef NEW_DEMUXER
vlen = Demuxer::getInstance()->writeVideo(fd); // FIXME
+#else
+ threadCheckExit();
+ vlen = Demuxer::getInstance()->writeVideo(dt); // FIXME
+#endif
if (vlen)
{
// Log::getInstance()->log("VFeed", Log::DEBUG, "Written %i", vlen);
#include "log.h"
#include "demuxer.h"
#include "callback.h"
+#include "draintarget.h"
#ifdef WIN32
#include "threadwin.h"
{
public:
VFeed(Callback* tcb);
-
+#ifndef NEW_DEMUXER
int init(int fd);
+#else
+ int init(DrainTarget *tdt);
+#endif
+
int shutdown();
int start();
private:
void threadMethod();
void threadPostStopCleanup() {};
+#ifndef NEW_DEMUXER
int fd;
+#else
+ DrainTarget *dt;
+#endif
+
Callback& cb;
};
#include <stdio.h>
#include "defines.h"
+#include "draintarget.h"
-class Video
+class Video: public DrainTarget
{
public:
Video();
virtual ULONG timecodeToFrameNumber(ULLONG timecode)=0;
virtual int getFD()=0;
virtual ULLONG getCurrentTimestamp()=0;
+ virtual void turnVideoOn(){};
+ virtual void turnVideoOff(){};
#ifdef DEV
virtual int test() { return 0; }
#include "videomvp.h"
+// temp
+#include "log.h"
+
VideoMVP::VideoMVP()
{
if (instance) return;
if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
aspectRatio = taspectRatio;
+ Log::getInstance()->log("Video", Log::DEBUG, "Setting aspect to %i", aspectRatio);
+
if (ioctl(fdVideo, AV_SET_VID_RATIO, aspectRatio) != 0) return 0;
return 1;
}
return 0;
}
#endif
+
+// unused
+UINT VideoMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos)
+{
+ return 0;
+}
int getFD();
ULLONG getCurrentTimestamp();
+ //Writing Data to Videodevice
+ virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+ virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; };
+
#ifdef DEV
int test();
int test2();
*/
#include "videowin.h"
+#include "dssourcefilter.h"
+
+
+
+
VideoWin::VideoWin()
{
- if (instance) return;
+ dsgraphbuilder=NULL;
+ dsmediacontrol=NULL;
+ sourcefilter=NULL;
+ filtermutex=CreateMutex(NULL,FALSE,NULL);
+ offsetnotset=true;
+ offsetvideonotset=true;
+ offsetaudionotset=true;
+ startoffset=0;
+ lastrefaudiotime=0;
+ lastrefvideotime=0;
+ firstsynched=false;
+ cur_audio_media_sample=NULL;
+ cur_video_media_sample=NULL;
+ videoon=true;
+ audioon=true;
+
+
}
VideoWin::~VideoWin()
{
+ CleanupDS();
+ CloseHandle(filtermutex);
+
+
instance = NULL;
}
int VideoWin::init(UCHAR tformat)
{
if (initted) return 0;
+
initted = 1;
+ if (!setFormat(tformat)){ shutdown(); return 0; }
return 1;
}
if (!initted) return 0;
if ((tformat != PAL) && (tformat != NTSC)) return 0;
format = tformat;
+ if (format == NTSC)
+ {
+ screenWidth = 720;
+ screenHeight = 480;
+ }
+ if (format == PAL)
+ {
+ screenWidth = 720;
+ screenHeight = 576;
+ }
return 1;
}
return 1;
}
+#ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
+#include "dshelper.h"
+#endif
+
+#define DO_VIDEO
+
int VideoWin::play()
{
if (!initted) return 0;
+ //Build filter graph
+ HRESULT hres;
+ if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
+ IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
+ return 0;
+ }
+ #ifdef DS_DEBUG
+ AddToRot(dsgraphbuilder,&graphidentifier);
+ #endif
+ //This is just a try to see if building the graph works
+// dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
+ //So this is the real code, this prevents the feeder from calling noexisting objects!
+ WaitForSingleObject(filtermutex,INFINITE);
+ offsetnotset=true;
+ offsetvideonotset=true;
+ offsetaudionotset=true;
+ firstsynched=false;
+ sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
+ // to DirectShow
+ if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
+ CleanupDS();
+ ReleaseMutex(filtermutex);
+ return 0;
+ }
+ if (audioon) {
+ if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(0)/*audio*/)!=S_OK) {
+ CleanupDS();
+ ReleaseMutex(filtermutex);
+ return 0;
+ }
+ }
+#ifdef DO_VIDEO
+ if (videoon) {
+ if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(1)/*video*/)!=S_OK) {
+ CleanupDS();
+ ReleaseMutex(filtermutex);
+ return 0;
+ }
+ }
+#endif
+
+
+
+ dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
+ dsmediacontrol->Run();
+ ReleaseMutex(filtermutex);
return 1;
}
{
if (!initted) return 0;
+ CleanupDS();
+
+
return 1;
}
int VideoWin::pause()
{
if (!initted) return 0;
-
+ if (dsmediacontrol) dsmediacontrol->Pause();
return 1;
}
int VideoWin::unPause() // FIXME get rid - same as play!!
-{
+{//No on windows this is not the same, I don't get rid of!
if (!initted) return 0;
+ if (dsmediacontrol) dsmediacontrol->Run();
return 1;
}
else return (ULONG)(((double)timecode / (double)90000) * (double)30);
}
+void VideoWin::CleanupDS()
+{
+ WaitForSingleObject(filtermutex,INFINITE);
+ if (cur_audio_media_sample) {
+ cur_audio_media_sample->Release();
+ cur_audio_media_sample=NULL;
+ }
+ if (cur_video_media_sample) {
+ cur_video_media_sample->Release();
+ cur_video_media_sample=NULL;
+ }
+
+ if (dsmediacontrol) {
+ dsmediacontrol->Stop();
+ dsmediacontrol->Release();
+ dsmediacontrol=NULL;
+ }
+ if (dsgraphbuilder){
+#ifdef DS_DEBUG
+ RemoveFromRot(graphidentifier);
+#endif
+ dsgraphbuilder->Release();
+ dsgraphbuilder=NULL;
+ sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
+ }
+ ReleaseMutex(filtermutex);
+
+}
+
+
+UINT VideoWin::DeliverMediaSample(MediaPacket packet,
+ UCHAR* buffer,
+ UINT *samplepos)
+{
+ /*First Check, if we have an audio sample*/
+#ifdef DO_VIDEO
+ /*First Check, if we have an audio sample*/
+
+ IMediaSample* ms=NULL;
+ REFERENCE_TIME reftime1=0;
+ REFERENCE_TIME reftime2=0;
+
+ UINT headerstrip=0;
+ if (packet.disconti) {
+ firstsynched=false;
+ DeliverVideoMediaSample();
+
+ }
+
+
+ /*Inspect PES-Header */
+
+ if (*samplepos==0) {//stripheader
+ headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
+ *samplepos+=headerstrip;
+ if ( packet.synched ) {
+ DeliverVideoMediaSample();//write out old data
+ if (packet.presentation_time<0) { //Preroll?
+ *samplepos=packet.length;//if we have not processed at least one
+ return packet.length;//synched packet ignore it!
+ }
+
+ reftime1=packet.presentation_time;
+ reftime2=reftime1+1;
+ firstsynched=true;
+ } else {
+ if (!firstsynched) {//
+ *samplepos=packet.length;//if we have not processed at least one
+ return packet.length;//synched packet ignore it!
+ }
+ }
+ }
+ BYTE *ms_buf;
+ UINT ms_length;
+ UINT ms_pos;
+ UINT haveToCopy;
+ if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
+ samplepos=0;
+ MILLISLEEP(10);
+ return 0;
+ }
+ ms_pos=ms->GetActualDataLength();
+ ms_length=ms->GetSize();
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+ if ((ms_length-ms_pos)<1) {
+ DeliverVideoMediaSample(); //we are full!
+ if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
+ samplepos=0;
+ MILLISLEEP(10);
+ return 0;
+ }
+ ms_pos=ms->GetActualDataLength();
+ ms_length=ms->GetSize();
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
+ }
+ ms->GetPointer(&ms_buf);
+
+
+ if (ms_pos==0) {//will only be changed on first packet
+ if (packet.disconti) {
+ ms->SetDiscontinuity(TRUE);
+ } else {
+ ms->SetDiscontinuity(FALSE);
+ }
+ if (packet.synched) {
+ ms->SetSyncPoint(TRUE);
+ ms->SetTime(&reftime1,&reftime2);
+ //ms->SetTime(NULL,NULL);
+ ms->SetMediaTime(NULL, NULL);
+ }else {
+ ms->SetSyncPoint(FALSE);
+ ms->SetTime(NULL,NULL);
+ ms->SetMediaTime(NULL, NULL);
+ ms->SetSyncPoint(TRUE);
+ }
+ }
+
+
+ memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
+ ms->SetActualDataLength(haveToCopy+ms_pos);
+
+ *samplepos+=haveToCopy;
+
+ return haveToCopy+headerstrip;
+
+#else
+
+ *samplepos+=packet.length;
+ MILLISLEEP(0); //yet not implemented//bad idea
+ return packet.length;
+#endif
+}
+
+int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
+{
+ //WaitForSingleObject(filtermutex,INFINITE);
+ if (!sourcefilter){
+ // ReleaseMutex(filtermutex);
+ return 0;
+ }
+ if (cur_audio_media_sample) {
+ *ms=cur_audio_media_sample;//already open
+ return 1;
+ }
+ if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
+ // ReleaseMutex(filtermutex);
+ }
+ if (*ms) (*ms)->SetActualDataLength(0);
+ cur_audio_media_sample=*ms;
+ //Don't release the mutex before deliver
+ return 1;
+}
+
+int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
+{
+ //WaitForSingleObject(filtermutex,INFINITE);
+ if (!sourcefilter){
+ // ReleaseMutex(filtermutex);
+ return 0;
+ }
+ if (cur_video_media_sample) {
+ *ms=cur_video_media_sample;//already open
+ return 1;
+ }
+ if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
+ // ReleaseMutex(filtermutex);
+ }
+ if (*ms) (*ms)->SetActualDataLength(0);
+
+ cur_video_media_sample=*ms;
+ //Don't release the mutex before deliver
+ return 1;
+}
+
+int VideoWin::DeliverAudioMediaSample(){
+ if (cur_audio_media_sample) {
+ sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
+ cur_audio_media_sample=NULL;
+ }
+ //ReleaseMutex(filtermutex);
+ return 1;
+}
+
+int VideoWin::DeliverVideoMediaSample(){
+ if (cur_video_media_sample) {
+ sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
+ cur_video_media_sample=NULL;
+ }
+ //ReleaseMutex(filtermutex);
+ return 1;
+}
+
+long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
+{
+ *rsync=false;
+ if (offsetnotset) {
+ startoffset=curreftime;//offset is set for audio
+ offsetnotset=false;
+ offsetvideonotset=false;
+ } else {
+ if (offsetvideonotset) {
+ offsetvideonotset=false;
+ *rsync=true;
+ } else {
+ if ( (curreftime-lastrefvideotime)>10000000LL
+ || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
+ startoffset+=curreftime-lastrefvideotime;
+ //lastrefaudiotime+=curreftime-lastrefvideotime;
+ *rsync=true;
+ offsetaudionotset=true;
+
+ }
+ }
+
+ }
+ lastrefvideotime=curreftime;
+ return startoffset;
+
+}
+
+long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
+{
+ *rsync=false;
+ if (offsetnotset) {
+ startoffset=curreftime;
+ offsetnotset=false;
+ offsetaudionotset=false;
+ } else {
+ if (offsetaudionotset) {
+ offsetaudionotset=false;
+ *rsync=true;
+ } else {
+ if ( (curreftime-lastrefaudiotime)>10000000LL
+ || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
+ startoffset+=curreftime-lastrefaudiotime;
+ lastrefvideotime+=curreftime-lastrefaudiotime;
+ *rsync=true;
+ offsetvideonotset=true;
+
+ }
+ }
+
+ }
+ lastrefaudiotime=curreftime;
+ return startoffset;
+
+}
+
+
+
#ifdef DEV
int VideoWin::test()
{
#include <stdio.h>
#include <string.h>
+#include <winsock2.h>
+#include <dshow.h>
#include "defines.h"
#include "video.h"
+#define DS_DEBUG
+
+class DsSourceFilter;
+
class VideoWin : public Video
{
public:
int getFD();
ULLONG getCurrentTimestamp();
+ //Writing Data to Videodevice
+ virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);
+
+ int getCurrentAudioMediaSample(IMediaSample** ms);
+ int DeliverAudioMediaSample();
+
+ int getCurrentVideoMediaSample(IMediaSample** ms);
+ int DeliverVideoMediaSample();
+
+ long long SetStartOffset(long long curreftime, bool *rsync);
+ long long SetStartAudioOffset(long long curreftime, bool *rsync);
+
+ void SetAudioState(bool state){audioon=state;};
+
+ void turnVideoOn(){videoon=true;};
+ void turnVideoOff(){videoon=false;};
+
#ifdef DEV
int test();
int test2();
#endif
+private:
+ IMediaControl* dsmediacontrol;
+ IGraphBuilder* dsgraphbuilder;
+ IMediaSample* cur_audio_media_sample;
+ IMediaSample* cur_video_media_sample;
+
+ DsSourceFilter* sourcefilter;
+ HANDLE filtermutex;
+ void CleanupDS();
+ bool offsetnotset;
+ bool offsetvideonotset;
+ bool offsetaudionotset;
+ long long startoffset;
+ long long lastrefvideotime;
+ long long lastrefaudiotime;
+
+ bool firstsynched;
+ bool audioon;
+ bool videoon;
+#ifdef DS_DEBUG
+ DWORD graphidentifier;
+#endif
};
#endif
event = (*eventList)[i];
btime = localtime((time_t*)&event->time);
+#ifndef _MSC_VER
strftime(tempString2, 299, "%0H:%0M ", btime);
+#else
+ strftime(tempString2, 299, "%H:%M ", btime);
+#endif
SNPRINTF(tempString, 299, "%s %s", tempString2, event->title);
event->index = sl.addOption(tempString, first);
first = 0;
--- /dev/null
+
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef VOMPRESWIN_H
+#define _WIN32_WINNT 0x501
+
+#include <winsock2.h>
+#include <winuser.h>
+#define VOMPACCELERATOR 1
+
+#define VOMPRESWIN_H
+#endif
--- /dev/null
+
+
+#include "vompreswin.h"
+
+
+
+//1 TEXTINCLUDE
+//BEGIN
+// "#include ""winsock2.h""\r\n"
+// "#include ""vompreswin.h""\r\n"
+// "\0"
+//END
+
+
+
+
+
+VOMPACCELERATOR ACCELERATORS
+BEGIN
+ VK_INSERT, APPCOMMAND_MEDIA_CHANNEL_DOWN, VIRTKEY, CONTROL,
+ NOINVERT
+ VK_INSERT, APPCOMMAND_MEDIA_CHANNEL_DOWN, VIRTKEY, NOINVERT
+ VK_PRIOR, APPCOMMAND_MEDIA_CHANNEL_DOWN, VIRTKEY, NOINVERT
+ VK_OEM_PLUS, APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, CONTROL, NOINVERT
+ VK_OEM_PLUS, APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, NOINVERT
+ VK_NEXT, APPCOMMAND_MEDIA_CHANNEL_UP, VIRTKEY, NOINVERT
+ "F", APPCOMMAND_MEDIA_FAST_FORWARD, VIRTKEY, SHIFT, CONTROL,
+ NOINVERT
+ VK_F8, APPCOMMAND_VOLUME_MUTE, VIRTKEY, NOINVERT
+ "P", APPCOMMAND_MEDIA_PAUSE, VIRTKEY, CONTROL, NOINVERT
+ "P", APPCOMMAND_MEDIA_PLAY, VIRTKEY, SHIFT, CONTROL,
+ NOINVERT
+ "R", APPCOMMAND_MEDIA_RECORD, VIRTKEY, CONTROL, NOINVERT
+ "B", APPCOMMAND_MEDIA_PREVIOUSTRACK, VIRTKEY, CONTROL,
+ NOINVERT
+ "F", APPCOMMAND_MEDIA_NEXTTRACK, VIRTKEY, CONTROL, NOINVERT
+ "S", APPCOMMAND_MEDIA_STOP, VIRTKEY, CONTROL, NOINVERT
+ VK_F9, APPCOMMAND_VOLUME_DOWN, VIRTKEY, NOINVERT
+ VK_F10, APPCOMMAND_VOLUME_UP, VIRTKEY, NOINVERT
+END
+
+
+
{
rec = recDir->recList[j];
btime = localtime((time_t*)&rec->start);
+#ifndef _MSC_VER
strftime(tempA, 299, "%0d/%0m %0H:%0M ", btime);
+#else
+ strftime(tempA, 299, "%d/%m %H:%M ", btime);
+#endif
sprintf(tempB, "%s\t%s", tempA, rec->getProgName());
rec->index = sl.addOption(tempB, first);
first = 0;
viewman->updateView(v);
return 2;
}
+#ifdef DEV
+ case Remote::YELLOW:
+ {
+ player->test1();
+ break;
+ }
+ case Remote::BLUE:
+ {
+ player->test2();
+ break;
+ }
+#endif
}
return 1;
--- /dev/null
+/*
+ Copyright 2004-2005 Chris Tallon
+
+ This file is part of VOMP.
+
+ VOMP 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.
+
+ VOMP 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 VOMP; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifdef WIN32
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <windows.h>
+
+#include "vompreswin.h"
+
+#include "defines.h"
+#include "log.h"
+#include "remotewin.h"
+#include "ledwin.h"
+#include "mtdwin.h"
+#include "timers.h"
+#include "videowin.h"
+#include "audiowin.h"
+#include "vdr.h"
+#include "osdwin.h"
+#include "viewman.h"
+#include "command.h"
+
+void sighandler(int signalReceived);
+void shutdown(int code);
+
+// Global variables --------------------------------------------------------------------------------------------------
+int debugEnabled = 0;
+Log* logger;
+Remote* remote;
+Mtd* mtd;
+Led* led;
+Osd* osd;
+Timers* timers;
+ViewMan* viewman;
+Command* command;
+VDR* vdr;
+Video* video;
+Audio* audio;
+
+
+void MILLISLEEP(ULONG a)
+{
+
+ Sleep(a);
+
+}
+
+DWORD WINAPI commandthreadStart(void *arg)
+{
+ command->run();
+ return 0;
+}
+
+bool InitApp(HINSTANCE hinst,int cmdshow);
+
+HWND win;//global window handle
+HACCEL acc;
+
+#define ERROR_MSG(str) MessageBox(win,str,"Error!",MB_OK|MB_ICONWARNING)
+INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmdshow)
+{
+ //On Windows we have to init a window, we use DXUT
+ if (!InitApp(hinst,cmdshow)) return false;
+ //Starting Network support
+ WSADATA wsadat;
+ int result = WSAStartup(MAKEWORD(2,2),&wsadat);
+ if (result!=NO_ERROR) {
+ ERROR_MSG("Initialising WinSocked: Error at WSAStartup()\n");
+ return 0;
+ }
+ result= CoInitializeEx(NULL,COINIT_MULTITHREADED );//Initialize COM for DirectShow
+ if (result!=S_OK) {
+ ERROR_MSG("Initialising COM: Error at Coinitialize()\n");
+ return 0;
+ }
+
+
+
+
+ // Init global vars ------------------------------------------------------------------------------------------------
+
+ logger = new Log();
+ remote = new RemoteWin();
+ mtd = new MtdWin();
+ led = new LedWin();
+ timers = new Timers();
+ osd = new OsdWin();
+ vdr = new VDR();
+ video = new VideoWin();
+ audio = new AudioWin();
+ viewman = new ViewMan();
+ command = new Command();
+
+ if (!logger || !remote || !mtd || !led || !osd || !video || !audio || !viewman || !command)
+ {
+ ERROR_MSG("Could not create objects. Memory problems?\n");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ // Get logging module started --------------------------------------------------------------------------------------
+
+ if (!logger->init(Log::DEBUG, "vompwin.log", true))
+ {
+ ERROR_MSG("Could not initialise log object. Aborting.\n");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ logger->log("Core", Log::INFO, "Starting up...");
+
+
+
+ // Init modules ----------------------------------------------------------------------------------------------------
+ int success;
+
+ success = remote->init("/dev/rawir");
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Remote module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Remote module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = led->init(0);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "LED module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "LED module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = mtd->init("/dev/mtd1");
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Mtd module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Mtd module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = timers->init();
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Timers module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Timers module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC();
+ if (videoFormat == Video::PAL) logger->log("Core", Log::INFO, "Read from MTD: PAL 720x576");
+ else if (videoFormat == Video::NTSC) logger->log("Core", Log::INFO, "Read from MTD: NTSC 720x480");
+ else logger->log("Core", Log::INFO, "No help from MTD. Assuming NTSC 720x480");
+
+ success = video->init(videoFormat);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Video module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Video module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = osd->init((void*)&win);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "OSD module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "OSD module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = audio->init(Audio::MPEG2_PES);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Audio module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Audio module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = vdr->init(3024);
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "VDR module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "VDR module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = viewman->init();
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "ViewMan module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "ViewMan module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ success = command->init();
+ if (success)
+ {
+ logger->log("Core", Log::INFO, "Command module initialised");
+ }
+ else
+ {
+ logger->log("Core", Log::EMERG, "Command module failed to initialise");
+ shutdown(1);
+ WSACleanup();
+ return 0;
+ }
+
+ // Other init ------------------------------------------------------------------------------------------------------
+
+ logger->log("Core", Log::NOTICE, "Startup successful");
+
+ // Run main loop ---------------------------------------------------------------------------------------------------
+
+ // Ok, all major device components and other bits are loaded and ready
+
+ HANDLE commandthread;
+ commandthread= CreateThread(NULL, 0, commandthreadStart, NULL,0,
+ NULL);
+ MSG message;
+ message.message=WM_NULL;
+ bool run=true;
+ while(run && WaitForSingleObject(commandthread,0)==WAIT_TIMEOUT) {
+ if (PeekMessage(&message, NULL, 0,0,PM_REMOVE)!=0) {
+ if (TranslateAccelerator(win,acc,&message)==NULL) {
+ TranslateMessage(&message);
+ DispatchMessage(&message);
+ switch (message.message) {
+ case WM_QUIT:
+ run=false; //TODO post exit to command Messages
+ };
+ }
+ } else {
+ //Render
+ ((OsdWin*)osd)->Render();
+ }
+ }
+ // When that returns quit ------------------------------------------------------------------------------------------
+ WaitForSingleObject(commandthread,INFINITE);
+ shutdown(0);
+ WSACleanup();
+ return 0;
+
+}
+
+LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ switch (msg) {
+ case WM_DESTROY: {
+ //TODO: call command
+ logger->log("Core", Log::NOTICE, "Window closed, shutting down...");
+ command->stop(); // FIXME this is probably not safe - use the messaging system / is that even safe?
+ ((RemoteWin*)Remote::getInstance())->Signal();
+ PostQuitMessage(0);
+ }break;
+ case WM_SIZE: {
+ int width = LOWORD(lparam);
+ int height = HIWORD(lparam);
+ //Call device
+ }
+ break;
+ case WM_PAINT:
+ RECT r;
+ PAINTSTRUCT ps;
+ if (GetUpdateRect(win, &r, FALSE)) {
+ BeginPaint(win, &ps);
+ //Call Painting Mechanism
+ EndPaint(win, &ps);
+ }
+ break;
+ case WM_KEYDOWN:
+ if (((RemoteWin*)remote)->ReceiveButtonVK(wparam)) {
+ return 0L; //We process that Key
+ } else {
+ return DefWindowProc(win, msg, wparam, lparam);
+ }
+
+ break;
+ case WM_APPCOMMAND:
+ if (((RemoteWin*)remote)->ReceiveButtonAP(GET_APPCOMMAND_LPARAM(lparam))){
+ return TRUE; //yes we process that message
+ } else {
+ return DefWindowProc(win, msg, wparam, lparam);
+ }
+
+ break;
+ case WM_COMMAND:
+ if (((RemoteWin*)remote)->ReceiveButtonAP(LOWORD(wparam))){
+ return 0; //yes we process that message
+ } else {
+ return DefWindowProc(win, msg, wparam, lparam);
+ }
+
+ break;
+ default:
+ return DefWindowProc(win, msg, wparam, lparam);
+ }
+ return 0L;
+}
+
+
+bool InitApp(HINSTANCE hinst,int cmdshow) {
+ WNDCLASS wcs;
+ DWORD flags;
+ wcs.style = CS_HREDRAW | CS_VREDRAW;
+ wcs.lpfnWndProc = WindowProc;
+ wcs.cbClsExtra = 0;
+ wcs.cbWndExtra = sizeof(DWORD);
+ wcs.hInstance = hinst;
+ wcs.hIcon = NULL;
+ wcs.hCursor = NULL;
+ wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ wcs.lpszMenuName = NULL;
+ wcs.lpszClassName = "vomp";
+ acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR));
+ if (!RegisterClass(&wcs))
+ return false;
+ flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU
+ |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX;
+ RECT wnted={0,0,720,576};
+ AdjustWindowRect(&wnted,flags ,false);
+ win=CreateWindow("vomp","vomp",flags, CW_USEDEFAULT,CW_USEDEFAULT,
+ wnted.right-wnted.left,wnted.bottom-wnted.top,NULL,NULL,hinst,NULL);
+ if (!win)
+ return FALSE;
+ ShowWindow(win,SW_SHOWNORMAL);
+ UpdateWindow(win);
+ return TRUE;
+}
+
+
+
+
+
+// -------------------------------------------------------------------------------------------------------------------
+
+void shutdown(int code)
+{
+ if (viewman)
+ {
+ viewman->shutdown();
+ delete viewman;
+ logger->log("Core", Log::NOTICE, "ViewMan module shut down");
+ }
+
+ if (command) // shut down command here in case views have posted messages
+ {
+ command->shutdown();
+ delete command;
+ logger->log("Core", Log::NOTICE, "Command module shut down");
+ }
+
+ if (vdr)
+ {
+ vdr->shutdown();
+ delete vdr;
+ logger->log("Core", Log::NOTICE, "VDR module shut down");
+ }
+
+ if (osd)
+ {
+ osd->shutdown();
+ delete osd;
+ logger->log("Core", Log::NOTICE, "OSD module shut down");
+ }
+
+ if (audio)
+ {
+ audio->shutdown();
+ delete audio;
+ logger->log("Core", Log::NOTICE, "Audio module shut down");
+ }
+
+ if (video)
+ {
+ video->shutdown();
+ delete video;
+ logger->log("Core", Log::NOTICE, "Video module shut down");
+ }
+
+ if (timers)
+ {
+ timers->shutdown();
+ delete timers;
+ logger->log("Core", Log::NOTICE, "Timers module shut down");
+ }
+
+ if (mtd)
+ {
+ mtd->shutdown();
+ delete mtd;
+ logger->log("Core", Log::NOTICE, "MTD module shut down");
+ }
+
+ if (led)
+ {
+ led->shutdown();
+ delete led;
+ logger->log("Core", Log::NOTICE, "LED module shut down");
+ }
+
+ if (remote)
+ {
+ remote->shutdown();
+ delete remote;
+ logger->log("Core", Log::NOTICE, "Remote module shut down");
+ }
+
+ if (logger)
+ {
+ logger->log("Core", Log::NOTICE, "Log module shutting down... bye!\n\n");
+ logger->shutdown();
+ delete logger;
+ }
+ ExitProcess(0);
+
+}
+
+// -------------------------------------------------------------------------------------------------------------------
+
+ULLONG ntohll(ULLONG a)
+{
+ return htonll(a);
+}
+
+ULLONG htonll(ULLONG a)
+{
+/*
+ #if BYTE_ORDER == BIG_ENDIAN
+ return a;
+ #else
+ ULLONG b = 0;
+
+ b = ((a << 56) & 0xFF00000000000000ULL)
+ | ((a << 40) & 0x00FF000000000000ULL)
+ | ((a << 24) & 0x0000FF0000000000ULL)
+ | ((a << 8) & 0x000000FF00000000ULL)
+ | ((a >> 8) & 0x00000000FF000000ULL)
+ | ((a >> 24) & 0x0000000000FF0000ULL)
+ | ((a >> 40) & 0x000000000000FF00ULL)
+ | ((a >> 56) & 0x00000000000000FFULL) ;
+
+ return b;
+ #endif*///This macro switching does not work for windows, here is a implementation without
+ // using BYTE_ORDER
+ //#define ntohll(x) (((_int64)(ntohl((int)((x << 32) >> 32))) << 32) |
+ // (unsigned int)ntohl(((int)(x >> 32)))) //By Runner
+
+ return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32)
+ |(ULONG)htonl(((ULONG) (a >> 32))));
+}
+#endif
\ No newline at end of file
free(buffer);
logger->log("BJpeg", Log::DEBUG, "deleted buffer");
+#else
+ DWORD width,height;
+ width=height=1;
+ ((SurfaceWin*)surface)->drawJpeg(fileName+1,offsetX,offsetY,&width,&height);//This should went into the abstract base classes?
+ //Windows has a problem with the leading / fixme
+ setDimensions(width, height);
#endif
}