From e0d48ce15cb24662c783bd60d2c81c5d70232ca7 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 7 May 2006 23:58:51 +0000 Subject: [PATCH] Windows port --- audiomvp.cc | 5 + audiomvp.h | 1 + audiowin.cc | 27 +++-- audiowin.h | 2 + draintarget.h | 4 +- dsock.cc | 57 +++++++--- dsock.h | 14 +-- dssourcefilter.h | 27 ++--- dssourcepin.cc | 125 ++++++++++++---------- threadwin.cc | 258 +++++++++++++++++++++++---------------------- vdr.cc | 46 +++++++- vdr.h | 3 + video.h | 6 +- videomvp.cc | 4 + videomvp.h | 1 + videowin.cc | 178 ++++++++++++++++++++++++++----- videowin.h | 21 +++- vrecordinglist.cc | 5 + winmain.cc | 262 +++++++++++++++++++++++++++++----------------- 19 files changed, 690 insertions(+), 356 deletions(-) diff --git a/audiomvp.cc b/audiomvp.cc index d9218c6..1a42351 100644 --- a/audiomvp.cc +++ b/audiomvp.cc @@ -246,3 +246,8 @@ UINT AudioMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *sampl { return 0; } + +void AudioMVP::ResetTimeOffsets() +{ +} + diff --git a/audiomvp.h b/audiomvp.h index a9223b3..cf29478 100644 --- a/audiomvp.h +++ b/audiomvp.h @@ -60,6 +60,7 @@ class AudioMVP : public Audio //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; }; + virtual void ResetTimeOffsets(); #ifdef DEV int test(); diff --git a/audiowin.cc b/audiowin.cc index db3f932..40b51b6 100644 --- a/audiowin.cc +++ b/audiowin.cc @@ -29,12 +29,14 @@ AudioWin::AudioWin() { initted = 0; firstsynched=false; + } AudioWin::~AudioWin() { + } @@ -165,10 +167,10 @@ UINT AudioWin::DeliverMediaSample(MediaPacket packet, *samplepos+=headerstrip; if ( packet.synched ) { vw->DeliverAudioMediaSample();//write out old data - if (packet.presentation_time<0) { //Preroll? + /* 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; @@ -185,9 +187,9 @@ UINT AudioWin::DeliverMediaSample(MediaPacket packet, UINT ms_pos; UINT haveToCopy; if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample - samplepos=0; + //samplepos=0; MILLISLEEP(10); - return 0; + return *samplepos; } ms_pos=ms->GetActualDataLength(); ms_length=ms->GetSize(); @@ -195,9 +197,9 @@ UINT AudioWin::DeliverMediaSample(MediaPacket packet, if ((ms_length-ms_pos)<1) { vw->DeliverAudioMediaSample(); //we are full! if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample - samplepos=0; + //samplepos=0; MILLISLEEP(10); - return 0; + return *samplepos; } ms_pos=ms->GetActualDataLength(); ms_length=ms->GetSize(); @@ -214,13 +216,18 @@ UINT AudioWin::DeliverMediaSample(MediaPacket packet, if (packet.synched) { ms->SetSyncPoint(TRUE); ms->SetTime(&reftime1,&reftime2); + //ms->SetTime(NULL,NULL); ms->SetMediaTime(NULL, NULL); + if (reftime1<0) ms->SetPreroll(TRUE); + else ms->SetPreroll(FALSE); }else { ms->SetSyncPoint(FALSE); ms->SetTime(NULL,NULL); ms->SetMediaTime(NULL, NULL); - ms->SetSyncPoint(TRUE); + ms->SetPreroll(FALSE); + MessageBox(0,"here I'm","Hallo",0); + // ms->SetSyncPoint(TRUE); } } @@ -239,9 +246,15 @@ long long AudioWin::SetStartOffset(long long curreftime, bool *rsync){ return vw->SetStartAudioOffset(curreftime,rsync); } +void AudioWin::ResetTimeOffsets() { + VideoWin *vw=(VideoWin*)Video::getInstance(); + return vw->ResetTimeOffsets(); +} + #ifdef DEV int AudioWin::test() { return 0; } #endif + diff --git a/audiowin.h b/audiowin.h index a31bf91..2e6eb1a 100644 --- a/audiowin.h +++ b/audiowin.h @@ -52,6 +52,7 @@ class AudioWin : public Audio // Writing Data to Audiodevice virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos); virtual long long SetStartOffset(long long curreftime, bool *rsync); + virtual void ResetTimeOffsets(); private: bool firstsynched; @@ -61,3 +62,4 @@ private: }; #endif + diff --git a/draintarget.h b/draintarget.h index 4196e2a..7923b2e 100644 --- a/draintarget.h +++ b/draintarget.h @@ -58,9 +58,11 @@ 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; + virtual void ResetTimeOffsets()=0; }; -#endif \ No newline at end of file +#endif + diff --git a/dsock.cc b/dsock.cc index 0d65c77..4d7d98b 100644 --- a/dsock.cc +++ b/dsock.cc @@ -20,22 +20,39 @@ #include "dsock.h" +ULONG DatagramSocket::iterate_ip = 0; + DatagramSocket::DatagramSocket(short port) { theInstance = this; myPort = port; addrlen = sizeof(struct sockaddr); +} + +DatagramSocket::~DatagramSocket() +{ + CLOSESOCKET(socketnum); +} + +DatagramSocket* DatagramSocket::theInstance = 0; +DatagramSocket* DatagramSocket::getInstance(void) +{ + return theInstance; +} +int DatagramSocket::init() +{ + CLOSESOCKET(socketnum); if ((socketnum = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - { perror("socket"); exit(1); } + { perror("socket"); return 0; } myAddr.sin_family = AF_INET; // host byte order myAddr.sin_port = htons(myPort); // short, network byte order - myAddr.sin_addr.s_addr = INADDR_ANY; // auto-fill with my IP + myAddr.sin_addr.s_addr = getIPNumber(iterate_ip++); // auto-fill with my IP memset(&(myAddr.sin_zero), 0, 8); // zero the rest of the struct if (bind(socketnum, (struct sockaddr *)&myAddr, addrlen) == -1) - { perror("bind"); exit(1); } + { perror("bind"); return 0; } FD_ZERO(&readfds); FD_SET(socketnum, &readfds); @@ -44,17 +61,8 @@ DatagramSocket::DatagramSocket(short port) int allowed = 1; setsockopt(socketnum, SOL_SOCKET, SO_BROADCAST, (char*)&allowed, sizeof(allowed)); -} -DatagramSocket::~DatagramSocket() -{ - CLOSESOCKET(socketnum); -} - -DatagramSocket* DatagramSocket::theInstance = 0; -DatagramSocket* DatagramSocket::getInstance(void) -{ - return theInstance; + return 1; } unsigned char DatagramSocket::waitforMessage(unsigned char how) @@ -188,3 +196,26 @@ void DatagramSocket::send(char *ipa, short port, char *message, int length) } } +ULONG DatagramSocket::getIPNumber(ULONG num) +{ + char buffer[100]; + ULONG returnaddress; + + if (gethostname(buffer,sizeof(buffer))==SOCKET_ERROR) + { + return INADDR_ANY; //well take any address, if we fail + } + + struct hostent *hosts=gethostbyname(buffer); + if (hosts==NULL) + { + return INADDR_ANY; //well take any address, if we fail + } + + int num_ip=0; + for (num_ip=0;hosts->h_addr_list[num_ip]!=NULL;num_ip++); + + int get_ip=(num%num_ip);//Just wrap around, if no interface are present any more + memcpy(&returnaddress, hosts->h_addr_list[get_ip], sizeof(ULONG)); + return returnaddress; +} diff --git a/dsock.h b/dsock.h index ba99d47..734bd05 100644 --- a/dsock.h +++ b/dsock.h @@ -22,23 +22,20 @@ #define DSOCK_H #ifndef WIN32 - #include +#include #include #include #include +#include +#define SOCKET_ERROR 0 #else #include #include +#include #endif - #include -#ifndef WIN32 -#include -#else -#include -#endif #include #include #include @@ -53,6 +50,7 @@ class DatagramSocket DatagramSocket(short); // port ~DatagramSocket(); static DatagramSocket* getInstance(void); + int init(); unsigned char waitforMessage(unsigned char); // int =0-block =1-new wait =2-continue wait int getDataLength(void) const; char *getData(void); // returns a pointer to the data @@ -61,6 +59,8 @@ class DatagramSocket void send(char *, short, char *, int); // send wants: IP Address ddn style, port, // data, length of data private: + ULONG getIPNumber(ULONG num); + static ULONG iterate_ip; const static char DSOCKDEBUG = 0; static DatagramSocket* theInstance; int socketnum; // Socket descriptor diff --git a/dssourcefilter.h b/dssourcefilter.h index e0d4597..c23c995 100644 --- a/dssourcefilter.h +++ b/dssourcefilter.h @@ -27,21 +27,22 @@ [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); + 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); + REFERENCE_TIME getStartOffset(){return m_tStart;}; protected: - CCritSec crit_sec; - DsSourcePin *audiopin; - DsSourcePin *videopin; + CCritSec crit_sec; + DsSourcePin *audiopin; + DsSourcePin *videopin; }; -#endif \ No newline at end of file +#endif diff --git a/dssourcepin.cc b/dssourcepin.cc index 70286ee..0ce629a 100644 --- a/dssourcepin.cc +++ b/dssourcepin.cc @@ -23,57 +23,57 @@ #include DsSourcePin::DsSourcePin(DsSourceFilter *pFilter, - CCritSec *pLock,HRESULT *phr,LPCWSTR pName,bool audio): + CCritSec *pLock,HRESULT *phr,LPCWSTR pName,bool audio): CBaseOutputPin(NAME("dssourcepin"),pFilter,pLock,phr,pName) { - isaudiopin=audio; - m_pFilter=pFilter; + 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; - - + 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); + 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; @@ -84,11 +84,11 @@ HRESULT DsSourcePin::GetMediaType(int iPosition, CMediaType *pmt) 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 ; + } else { + hr=VFW_S_NO_MORE_ITEMS; + } + } + return hr ; } // No description @@ -99,45 +99,54 @@ HRESULT DsSourcePin::CheckMediaType(const CMediaType *pmt) if (isaudiopin) { bool subtype=false; #if 0 /* For future demands ac3 */ - subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3); + subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3); #endif - subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO)); + subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO)); if (pmt->majortype==MEDIATYPE_Audio && subtype) { - res = S_OK ; + res = S_OK ; } else { res = S_FALSE ; - } + } } else { if (pmt->majortype==MEDIATYPE_Video && pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO) { - res = S_OK ; + res = S_OK ; } else { res = S_FALSE ; - } + } } return res; } HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){ - HRESULT hr; + 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; - } + if (isaudiopin) { + if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024) + { + all_pp->cBuffers = 300; + all_pp->cbBuffer = 64*1024; + } + } else { + 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)) + if (FAILED(hr)) { return hr; } - if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer) + 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 +} diff --git a/threadwin.cc b/threadwin.cc index 2d445bd..4d1daf7 100644 --- a/threadwin.cc +++ b/threadwin.cc @@ -1,126 +1,132 @@ -/* - 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 "threadwin.h" - -// Undeclared functions, only for use in this file to start the thread -DWORD WINAPI threadInternalStart(void *arg) -{ - Thread *t = (Thread *)arg; - t->threadInternalStart2(); - return 0; -} - -int ThreadWin::threadStart() -{ - threadCond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL); - if (threadCond == NULL) return 0; - threadCondMutex = CreateMutex(NULL,FALSE,NULL); - if (threadCondMutex == NULL) - { - CloseHandle(threadCond); - return 0; - } - - threadActive = 1; - DWORD threadId; - pthread = CreateThread(NULL, 0, threadInternalStart, (void*)this,0, &threadId); - if (pthread == NULL) - { - CloseHandle(threadCond); - CloseHandle(threadCondMutex); - return 0; - } - return 1; -} - -void ThreadWin::threadStop() -{ - threadActive = 0; - // Signal thread here in case it's waiting - threadSignal(); - WaitForSingleObject(pthread, INFINITE); - this->threadPostStopCleanup(); -} - -void ThreadWin::threadCancel() -{ - threadActive = 0; - //TerminateThread(pthread, 0); - threadSignalNoLock(); - WaitForSingleObject(pthread, INFINITE); - this->threadPostStopCleanup(); -} - -void ThreadWin::threadCheckExit() -{ - if (!threadActive) ExitThread(NULL); -} - -void ThreadWin::threadLock() -{ - WaitForSingleObject(threadCondMutex, INFINITE); -} - -void ThreadWin::threadUnlock() -{ - ReleaseMutex(threadCondMutex); -} - -void ThreadWin::threadSignal() -{ - WaitForSingleObject(threadCondMutex, INFINITE); - // PulseEvent(threadCond); - SetEvent(threadCond); - ReleaseMutex(threadCondMutex); -} - -void ThreadWin::threadSignalNoLock() -{ -// 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)+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() -{ - //WIN32:Ignore or use a separate Event Object to simulate this -} +/* + 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 "threadwin.h" + +// Undeclared functions, only for use in this file to start the thread +DWORD WINAPI threadInternalStart(void *arg) +{ + Thread *t = (Thread *)arg; + t->threadInternalStart2(); + return 0; +} + +int ThreadWin::threadStart() +{ + threadCond = CreateEvent(NULL,/*FALSE*/TRUE,FALSE,NULL); + if (threadCond == NULL) return 0; + threadCondMutex = CreateMutex(NULL,FALSE,NULL); + if (threadCondMutex == NULL) + { + CloseHandle(threadCond); + return 0; + } + + threadActive = 1; + DWORD threadId; + pthread = CreateThread(NULL, 0, threadInternalStart, (void*)this,0, &threadId); + if (pthread == NULL) + { + CloseHandle(threadCond); + CloseHandle(threadCondMutex); + return 0; + } + return 1; +} + +void ThreadWin::threadStop() +{ + threadActive = 0; + // Signal thread here in case it's waiting + threadSignal(); + WaitForSingleObject(pthread, INFINITE); + this->threadPostStopCleanup(); +} + +void ThreadWin::threadCancel() +{ + threadActive = 0; + //TerminateThread(pthread, 0); + threadSignalNoLock(); + WaitForSingleObject(pthread, INFINITE); + this->threadPostStopCleanup(); +} + +void ThreadWin::threadCheckExit() +{ + if (!threadActive) ExitThread(NULL); +} + +void ThreadWin::threadLock() +{ + WaitForSingleObject(threadCondMutex, INFINITE); +} + +void ThreadWin::threadUnlock() +{ + ReleaseMutex(threadCondMutex); +} + +void ThreadWin::threadSignal() +{ + WaitForSingleObject(threadCondMutex, INFINITE); + // PulseEvent(threadCond); + SetEvent(threadCond); + ReleaseMutex(threadCondMutex); +} + +void ThreadWin::threadSignalNoLock() +{ +// 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=(((LONGLONG)ts->tv_sec)*1000LL*1000LL*10LL+((LONGLONG)ts->tv_nsec)/100LL)+WINDOWS_TIME_BASE_OFFSET; + SYSTEMTIME debug; + FILETIME debugfile; + GetSystemTime(&debug); + SystemTimeToFileTime(&debug,&debugfile); + + 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() +{ + //WIN32:Ignore or use a separate Event Object to simulate this +} + diff --git a/vdr.cc b/vdr.cc index 2db53f8..5000667 100644 --- a/vdr.cc +++ b/vdr.cc @@ -26,8 +26,8 @@ VDR* VDR::instance = NULL; #define MUTEX_LOCK(mutex) pthread_mutex_lock(mutex) #define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex) #else -#define MUTEX_LOCK(mutex) WaitForSingleObject(mutex, INFINITE ) -#define MUTEX_UNLOCK(mutex) ReleaseMutex(mutex) +#define MUTEX_LOCK(mutex) WaitForSingleObject(*(mutex), INFINITE ) +#define MUTEX_UNLOCK(mutex) ReleaseMutex(*(mutex)) #endif @@ -41,7 +41,7 @@ VDR::VDR() #ifndef WIN32 pthread_mutex_init(&mutex, NULL); #else - mutex=CreateMutex(NULL,TRUE,NULL); + mutex=CreateMutex(NULL,FALSE,NULL); #endif packetLength = 0; packetPos = 0; @@ -84,8 +84,8 @@ void VDR::findServers(vector& servers) { findingServer = 1; char* message = "VOMP"; - DatagramSocket ds(port); + DatagramSocket ds(port); int haveAtLeastOne = 0; int retval; int waitType = 1; @@ -93,6 +93,7 @@ void VDR::findServers(vector& servers) { if (waitType == 1) { + ds.init(); logger->log("VDR", Log::NOTICE, "Broadcasting for server"); ds.send("255.255.255.255", 3024, message, strlen(message)); } @@ -757,6 +758,43 @@ ULLONG VDR::positionFromFrameNumber(ULONG frameNumber) return position; } +ULONG VDR::frameNumberFromPosition(ULLONG position) +{ + unsigned long totalLength = 16; + UCHAR* buffer = new UCHAR[totalLength]; + + *(unsigned long*)&buffer[0] = htonl(totalLength - 4); + *(unsigned long*)&buffer[4] = htonl(VDR_FRAMEFROMPOS); + *(ULLONG*)&buffer[8] = htonll(position); + + MUTEX_LOCK(&mutex); + if (!connected) { MUTEX_UNLOCK(&mutex); return 0; } + + unsigned int a = tcp->sendPacket(buffer, totalLength); + delete []buffer; + + if (a != totalLength) + { + disconnect(); + MUTEX_UNLOCK(&mutex); + return 0; + } + + if (!getPacket()) + { + MUTEX_UNLOCK(&mutex); + return 0; + } + + ULONG framenumber = extractULONG(); + freePacket(); + MUTEX_UNLOCK(&mutex); + + Log::getInstance()->log("VDR", Log::DEBUG, "VDR said new framenumber is: %u", framenumber); + + return framenumber; +} + EventList* VDR::getChannelSchedule(ULONG number) { time_t now; diff --git a/vdr.h b/vdr.h index 7bb4170..aeb7b58 100644 --- a/vdr.h +++ b/vdr.h @@ -141,6 +141,7 @@ class VDR ULLONG streamRecording(Recording* rec); ULLONG rescanRecording(); ULLONG positionFromFrameNumber(ULONG frameNumber); + ULONG frameNumberFromPosition(ULLONG position); ChannelList* getChannelsList(ULONG type); int streamChannel(ULONG number); @@ -195,6 +196,7 @@ class VDR const static ULONG VDR_GETTIMERS = 14; const static ULONG VDR_SETTIMER = 15; const static ULONG VDR_POSFROMFRAME = 16; + const static ULONG VDR_FRAMEFROMPOS = 17; int getPacket(); void freePacket(); @@ -206,3 +208,4 @@ class VDR }; #endif + diff --git a/video.h b/video.h index 91d0459..69de304 100644 --- a/video.h +++ b/video.h @@ -57,8 +57,10 @@ class Video: public DrainTarget virtual ULONG timecodeToFrameNumber(ULLONG timecode)=0; virtual int getFD()=0; virtual ULLONG getCurrentTimestamp()=0; - virtual void turnVideoOn(){}; - virtual void turnVideoOff(){}; + + virtual void turnVideoOn(){}; + virtual void turnVideoOff(){}; + virtual ULLONG frameNumberToTimecode(ULONG timecode) { return 0; }; #ifdef DEV virtual int test() { return 0; } diff --git a/videomvp.cc b/videomvp.cc index 8869322..6e7c61b 100644 --- a/videomvp.cc +++ b/videomvp.cc @@ -378,3 +378,7 @@ UINT VideoMVP::DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *sampl { return 0; } + +void VideoMVP::ResetTimeOffsets() +{ +} diff --git a/videomvp.h b/videomvp.h index b984185..f2a2aaf 100644 --- a/videomvp.h +++ b/videomvp.h @@ -72,6 +72,7 @@ class VideoMVP : public Video //Writing Data to Videodevice virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos); virtual long long SetStartOffset(long long curreftime, bool *rsync) { return 0; }; + virtual void ResetTimeOffsets(); #ifdef DEV int test(); diff --git a/videowin.cc b/videowin.cc index f7e7da6..8c1962d 100644 --- a/videowin.cc +++ b/videowin.cc @@ -19,9 +19,12 @@ */ #include "videowin.h" +#include "log.h" #include "dssourcefilter.h" +#include "dsallocator.h" +#include "vdr.h" - +void AdjustWindow(); @@ -29,7 +32,12 @@ VideoWin::VideoWin() { dsgraphbuilder=NULL; dsmediacontrol=NULL; + dsvmrrenderer=NULL; + dsrefclock=NULL; + dsmediafilter=NULL; sourcefilter=NULL; + allocatorvmr=NULL; + dsvmrsurfnotify=NULL; filtermutex=CreateMutex(NULL,FALSE,NULL); offsetnotset=true; offsetvideonotset=true; @@ -42,6 +50,8 @@ VideoWin::VideoWin() cur_video_media_sample=NULL; videoon=true; audioon=true; + pseudotvsize=0; + } @@ -50,6 +60,7 @@ VideoWin::~VideoWin() { CleanupDS(); CloseHandle(filtermutex); + instance = NULL; @@ -60,18 +71,21 @@ int VideoWin::init(UCHAR tformat) if (initted) return 0; initted = 1; + tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV + if (!setFormat(tformat)){ shutdown(); return 0; } return 1; } int VideoWin::setTVsize(UCHAR ttvsize) { + pseudotvsize=ttvsize; return 1; } int VideoWin::setDefaultAspect() { - return setAspectRatio(tvsize); + return setAspectRatio(Video::ASPECT4X3); } int VideoWin::shutdown() @@ -114,7 +128,7 @@ int VideoWin::setAspectRatio(UCHAR taspectRatio) if (!initted) return 0; if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; aspectRatio = taspectRatio; - + AdjustWindow(); return 1; } @@ -122,11 +136,12 @@ int VideoWin::setMode(UCHAR tmode) { if (!initted) return 0; - if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode + //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH) && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0; mode = tmode; + AdjustWindow(); return 1; } @@ -174,6 +189,7 @@ int VideoWin::play() //Build filter graph HRESULT hres; + if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER, IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) { return 0; @@ -185,37 +201,88 @@ int VideoWin::play() // 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) { + Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!"); CleanupDS(); ReleaseMutex(filtermutex); return 0; } - if (audioon) { + //if (audioon) { if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(0)/*audio*/)!=S_OK) { + Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!"); 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; - } + if (videoon) { + //We alloc the vmr9 as next step + if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0, + CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) { + Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!"); + CleanupDS(); + ReleaseMutex(filtermutex); + } + /*VMR 9 stuff**/ + if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) { + CleanupDS(); + Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!"); + ReleaseMutex(filtermutex); + return 0; + } + IVMRFilterConfig9* vmrfilconfig; + if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) { + CleanupDS(); + Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!"); + ReleaseMutex(filtermutex); + return 0; + } + vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless); + vmrfilconfig->Release(); + + if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) { + CleanupDS(); + Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!"); + ReleaseMutex(filtermutex); + return 0; + } + allocatorvmr=new DsAllocator(); + dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr); + allocatorvmr->AdviseNotify(dsvmrsurfnotify); + + + + /*VMR 9 stuff end */ + IFilterGraph2*fg2=NULL; + if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) { + Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!"); + CleanupDS(); + ReleaseMutex(filtermutex); + return 0; + } + if (hres=fg2->RenderEx(sourcefilter->GetPin(1)/*video*/, + AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) { + Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!"); + CleanupDS(); + ReleaseMutex(filtermutex); + return 0; + } } #endif - - + if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER, + IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) { + return 0; + } + + dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter); + dsmediafilter->SetSyncSource(dsrefclock); dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol); + dsmediacontrol->Run(); ReleaseMutex(filtermutex); return 1; @@ -235,6 +302,7 @@ int VideoWin::reset() { if (!initted) return 0; + return 1; } @@ -284,7 +352,19 @@ int VideoWin::getFD() ULLONG VideoWin::getCurrentTimestamp() { - return 0; + REFERENCE_TIME cr_time,startoffset; + + if (!dsrefclock || !sourcefilter) return 0; + + dsrefclock->GetTime(&cr_time); + startoffset=sourcefilter->getStartOffset(); + cr_time-=startoffset; + cr_time-=lastreftimeRT; + ULLONG result=frameNumberToTimecode( + VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE)); + result+=(ULLONG)(cr_time/10000LL*90LL); + return result; + } ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode) @@ -293,6 +373,12 @@ ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode) else return (ULONG)(((double)timecode / (double)90000) * (double)30); } +ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber) +{ + if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25); + else return (ULLONG)(((double)framenumber * (double)90000) / (double)30); +} + void VideoWin::CleanupDS() { WaitForSingleObject(filtermutex,INFINITE); @@ -304,6 +390,28 @@ void VideoWin::CleanupDS() cur_video_media_sample->Release(); cur_video_media_sample=NULL; } + if (dsvmrsurfnotify) { + dsvmrsurfnotify->Release(); + dsvmrsurfnotify=NULL; + } + if (dsvmrrenderer) { + dsvmrrenderer->Release(); + dsvmrrenderer=NULL; + } + + if (allocatorvmr) { + allocatorvmr->Release(); + allocatorvmr=NULL; + } + + if (dsrefclock) { + dsrefclock->Release(); + dsrefclock=NULL; + } + if (dsmediafilter) { + dsmediafilter->Release(); + dsmediafilter=NULL; + } if (dsmediacontrol) { dsmediacontrol->Stop(); @@ -350,10 +458,10 @@ UINT VideoWin::DeliverMediaSample(MediaPacket packet, *samplepos+=headerstrip; if ( packet.synched ) { DeliverVideoMediaSample();//write out old data - if (packet.presentation_time<0) { //Preroll? + /* 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; @@ -402,11 +510,19 @@ UINT VideoWin::DeliverMediaSample(MediaPacket packet, ms->SetTime(&reftime1,&reftime2); //ms->SetTime(NULL,NULL); ms->SetMediaTime(NULL, NULL); + if (reftime1<0) ms->SetPreroll(TRUE); + else ms->SetPreroll(FALSE); + /*Timecode handling*/ + lastreftimeRT=reftime1; + lastreftimeBYTE=packet.recording_byte_pos; + }else { ms->SetSyncPoint(FALSE); ms->SetTime(NULL,NULL); ms->SetMediaTime(NULL, NULL); - ms->SetSyncPoint(TRUE); + ms->SetPreroll(FALSE); + + // ms->SetSyncPoint(TRUE); } } @@ -492,6 +608,8 @@ long long VideoWin::SetStartOffset(long long curreftime, bool *rsync) startoffset=curreftime;//offset is set for audio offsetnotset=false; offsetvideonotset=false; + + } else { if (offsetvideonotset) { offsetvideonotset=false; @@ -500,8 +618,8 @@ long long VideoWin::SetStartOffset(long long curreftime, bool *rsync) if ( (curreftime-lastrefvideotime)>10000000LL || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync startoffset+=curreftime-lastrefvideotime; - //lastrefaudiotime+=curreftime-lastrefvideotime; - *rsync=true; + lastrefaudiotime+=curreftime-lastrefvideotime; + //*rsync=true; offsetaudionotset=true; } @@ -520,7 +638,7 @@ long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync) startoffset=curreftime; offsetnotset=false; offsetaudionotset=false; - } else { + }else { if (offsetaudionotset) { offsetaudionotset=false; *rsync=true; @@ -529,7 +647,7 @@ long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync) || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync startoffset+=curreftime-lastrefaudiotime; lastrefvideotime+=curreftime-lastrefaudiotime; - *rsync=true; + //*rsync=true; offsetvideonotset=true; } @@ -540,7 +658,14 @@ long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync) return startoffset; } - +void VideoWin::ResetTimeOffsets() { + offsetnotset=true; //called from demuxer + offsetvideonotset=true; + offsetaudionotset=true; + startoffset=0; + lastrefaudiotime=0; + lastrefvideotime=0; +} #ifdef DEV @@ -554,3 +679,4 @@ int VideoWin::test2() return 0; } #endif + diff --git a/videowin.h b/videowin.h index 6b4f2cb..36e8052 100644 --- a/videowin.h +++ b/videowin.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "defines.h" #include "video.h" @@ -32,6 +34,7 @@ #define DS_DEBUG class DsSourceFilter; +class DsAllocator; class VideoWin : public Video { @@ -45,7 +48,10 @@ class VideoWin : public Video int setFormat(UCHAR format); int setConnection(UCHAR connection); int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching - int setMode(UCHAR mode); + UCHAR getAspectRatio(){return aspectRatio;}; + UCHAR getMode(){return mode;}; + UCHAR getPseudoTVsize() {return pseudotvsize;}; + int setMode(UCHAR mode); int setTVsize(UCHAR size); // Is the TV a widescreen? int setDefaultAspect(); int setSource(); @@ -63,6 +69,7 @@ class VideoWin : public Video int signalOff(); int attachFrameBuffer(); // What does this do? ULONG timecodeToFrameNumber(ULLONG timecode); + ULLONG frameNumberToTimecode(ULONG framenumber); int getFD(); ULLONG getCurrentTimestamp(); @@ -75,8 +82,9 @@ class VideoWin : public Video int getCurrentVideoMediaSample(IMediaSample** ms); int DeliverVideoMediaSample(); - long long SetStartOffset(long long curreftime, bool *rsync); + virtual long long SetStartOffset(long long curreftime, bool *rsync); long long SetStartAudioOffset(long long curreftime, bool *rsync); + virtual void ResetTimeOffsets(); void SetAudioState(bool state){audioon=state;}; @@ -92,8 +100,13 @@ private: IGraphBuilder* dsgraphbuilder; IMediaSample* cur_audio_media_sample; IMediaSample* cur_video_media_sample; + IBaseFilter* dsvmrrenderer; + IVMRSurfaceAllocatorNotify9 *dsvmrsurfnotify; + IReferenceClock *dsrefclock; + IMediaFilter* dsmediafilter; DsSourceFilter* sourcefilter; + DsAllocator* allocatorvmr; HANDLE filtermutex; void CleanupDS(); bool offsetnotset; @@ -106,9 +119,13 @@ private: bool firstsynched; bool audioon; bool videoon; + UCHAR pseudotvsize; + REFERENCE_TIME lastreftimeRT; + ULLONG lastreftimeBYTE; #ifdef DS_DEBUG DWORD graphidentifier; #endif }; #endif + diff --git a/vrecordinglist.cc b/vrecordinglist.cc index aea31ca..3965fd2 100644 --- a/vrecordinglist.cc +++ b/vrecordinglist.cc @@ -330,11 +330,16 @@ int VRecordingList::handleCommand(int command) case Remote::DF_DOWN: case Remote::DOWN: { + Log::getInstance()->log("P", Log::DEBUG, "1"); sl.down(); + Log::getInstance()->log("P", Log::DEBUG, "1.5"); sl.draw(); + Log::getInstance()->log("P", Log::DEBUG, "2"); doShowingBar(); + Log::getInstance()->log("P", Log::DEBUG, "3"); viewman->updateView(this); + Log::getInstance()->log("P", Log::DEBUG, "4"); return 2; } case Remote::SKIPBACK: diff --git a/winmain.cc b/winmain.cc index 5ad7e89..d1efe84 100644 --- a/winmain.cc +++ b/winmain.cc @@ -69,8 +69,8 @@ void MILLISLEEP(ULONG a) DWORD WINAPI commandthreadStart(void *arg) { - command->run(); - return 0; + command->run(); + return 0; } bool InitApp(HINSTANCE hinst,int cmdshow); @@ -82,18 +82,18 @@ HACCEL acc; 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; + if (!InitApp(hinst,cmdshow)) return false; //Starting Network support - WSADATA wsadat; + WSADATA wsadat; int result = WSAStartup(MAKEWORD(2,2),&wsadat); if (result!=NO_ERROR) { ERROR_MSG("Initialising WinSocked: Error at WSAStartup()\n"); - return 0; + 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; + ERROR_MSG("Initialising COM: Error at Coinitialize()\n"); + return 0; } @@ -117,8 +117,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { ERROR_MSG("Could not create objects. Memory problems?\n"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } // Get logging module started -------------------------------------------------------------------------------------- @@ -127,12 +127,12 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { ERROR_MSG("Could not initialise log object. Aborting.\n"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } logger->log("Core", Log::INFO, "Starting up..."); - + // Init modules ---------------------------------------------------------------------------------------------------- @@ -147,8 +147,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "Remote module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = led->init(0); @@ -160,8 +160,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "LED module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = mtd->init("/dev/mtd1"); @@ -173,8 +173,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "Mtd module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = timers->init(); @@ -186,8 +186,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "Timers module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } UCHAR videoFormat = (UCHAR)mtd->getPALorNTSC(); @@ -204,8 +204,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "Video module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = osd->init((void*)&win); @@ -217,8 +217,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "OSD module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = audio->init(Audio::MPEG2_PES); @@ -230,8 +230,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "Audio module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = vdr->init(3024); @@ -243,8 +243,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "VDR module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = viewman->init(); @@ -256,8 +256,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "ViewMan module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } success = command->init(); @@ -269,8 +269,8 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd { logger->log("Core", Log::EMERG, "Command module failed to initialise"); shutdown(1); - WSACleanup(); - return 0; + WSACleanup(); + return 0; } // Other init ------------------------------------------------------------------------------------------------------ @@ -280,27 +280,27 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd // 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); + 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(); - } + 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); @@ -310,23 +310,91 @@ INT WINAPI WinMain( HINSTANCE hinst , HINSTANCE previnst, LPSTR cmdline, int cmd } + + +void CalculateWindowSize(RECT * size,ULONG size_mode) { + DWORD width, height; + DWORD adjheight,adjwidth; + DWORD flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU + |WS_MINIMIZEBOX | WS_SIZEBOX |WS_MAXIMIZEBOX; + RECT wnted={50,50,150,150}; + AdjustWindowRect(&wnted,flags ,false); + adjwidth=-wnted.left+wnted.right-100; + adjheight=-wnted.top+wnted.bottom-100; + width=size->right-size->left-adjwidth; + height=size->bottom-size->top-adjheight; + UCHAR mode=video->getMode(); + UCHAR aspect=((VideoWin*)video)->getAspectRatio(); + UCHAR tvsize=((VideoWin*)video)->getPseudoTVsize(); + double aspectrt=4./3.; + if (tvsize==Video::ASPECT16X9) { + if (aspect==Video::ASPECT16X9) { + aspectrt=4./3.; //looks strange, but it is a 16:9 tv + } else if (aspect==Video::ASPECT4X3) { + aspectrt=4./3./(16./9.)*(4./3.); //I hope this is correct + } + } else if (tvsize==Video::ASPECT4X3) { + if (aspect==Video::ASPECT16X9) { + if (mode==Video::LETTERBOX) { + aspectrt=16./9.; + } else { + aspectrt=4./3.; + } + } if (aspect==Video::ASPECT4X3) { + aspectrt=4./3.; + } + } + switch (size_mode) { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMRIGHT: + case WMSZ_TOP: + case WMSZ_TOPRIGHT: + width=(ULONG)(((double)height)*aspectrt); + size->right=size->left+width+adjwidth; + break; + case WMSZ_BOTTOMLEFT: + case WMSZ_TOPLEFT: + width=(ULONG)(((double)height)*aspectrt); + size->left=size->right-width-adjwidth; + break; + case WMSZ_LEFT: + case WMSZ_RIGHT: + height=(ULONG)(((double)width)/aspectrt); + size->bottom=size->top+height+adjheight; + break; + } +} + +void AdjustWindow() { + RECT winrect; + GetWindowRect(win,&winrect); + CalculateWindowSize(&winrect,WMSZ_BOTTOM); + MoveWindow(win,winrect.left, + winrect.top,winrect.right-winrect.left,winrect.bottom-winrect.top,true); + +} + 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..."); + //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: { + ((RemoteWin*)Remote::getInstance())->Signal(); + PostQuitMessage(0); + }break; + case WM_SIZING: { + CalculateWindowSize((RECT*) lparam,wparam); + return TRUE; + }break; + case WM_SIZE: { int width = LOWORD(lparam); int height = HIWORD(lparam); //Call device } break; - case WM_PAINT: + case WM_PAINT: RECT r; PAINTSTRUCT ps; if (GetUpdateRect(win, &r, FALSE)) { @@ -335,30 +403,30 @@ LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam) 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; + 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); } @@ -367,9 +435,9 @@ LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam) bool InitApp(HINSTANCE hinst,int cmdshow) { - WNDCLASS wcs; - DWORD flags; - wcs.style = CS_HREDRAW | CS_VREDRAW; + WNDCLASS wcs; + DWORD flags; + wcs.style = CS_HREDRAW | CS_VREDRAW; wcs.lpfnWndProc = WindowProc; wcs.cbClsExtra = 0; wcs.cbWndExtra = sizeof(DWORD); @@ -379,20 +447,20 @@ bool InitApp(HINSTANCE hinst,int cmdshow) { wcs.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wcs.lpszMenuName = NULL; wcs.lpszClassName = "vomp"; - acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR)); - if (!RegisterClass(&wcs)) + acc=LoadAccelerators(hinst,MAKEINTRESOURCE(VOMPACCELERATOR)); + if (!RegisterClass(&wcs)) return false; - flags =WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU + 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) + RECT wnted={50,50,768+50,576+50}; + 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); + ShowWindow(win,SW_SHOWNORMAL); UpdateWindow(win); - return TRUE; + return TRUE; } @@ -509,11 +577,11 @@ ULLONG htonll(ULLONG a) 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) | + // 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)))); + return (((ULLONG)htonl((ULONG)((a<<32)>> 32))<<32) + |(ULONG)htonl(((ULONG) (a >> 32)))); } -#endif \ No newline at end of file +#endif -- 2.39.2