From fecafccdeb62fea04b8c56b8f577978e1b435de1 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sat, 20 May 2006 20:17:28 +0000 Subject: [PATCH] Windows port --- audiowin.cc | 517 ++++++++++--------- audiowin.h | 127 ++--- box.cc | 4 +- command.cc | 3 + osdwin.cc | 11 +- osdwin.h | 1 + player.cc | 4 + remotewin.cc | 6 + remotewin.h | 118 ++--- stream.cc | 51 +- stream.h | 10 + surface.cc | 2 +- vdr.cc | 5 +- videowin.cc | 1403 +++++++++++++++++++++++++------------------------- videowin.h | 273 +++++----- winmain.cc | 12 +- 16 files changed, 1340 insertions(+), 1207 deletions(-) diff --git a/audiowin.cc b/audiowin.cc index d835bb6..189731b 100644 --- a/audiowin.cc +++ b/audiowin.cc @@ -1,255 +1,264 @@ -/* - 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 "audiowin.h" -#include "videowin.h" - - - - - -AudioWin::AudioWin() -{ - initted = 0; - firstsynched=false; - - - -} - -AudioWin::~AudioWin() -{ - - -} - -int AudioWin::init(UCHAR tstreamType) -{ - if (initted) return 0; - initted = 1; - return 1; -} - -int AudioWin::shutdown() -{ - if (!initted) return 0; - initted = 0; - return 1; -} - -int AudioWin::write(char *buf, int len) -{ - return 0; //write(fdAudio, buf, len); -} - -int AudioWin::setStreamType(UCHAR type) -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::setChannel() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::setSource() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::sync() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::play() -{ - if (!initted) return 0; - firstsynched=false; - - return 1; -} - -int AudioWin::stop() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::pause() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::unPause() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::reset() -{ - if (!initted) return 0; - return 1; -} - -int AudioWin::setVolume(int tvolume) -{ - // parameter: 0 for silence, 20 for full - if ((tvolume < 0) || (tvolume > 20)) return 0; - 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 *samplepos; - } - 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 *samplepos; - } - 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); - if (reftime1<0) ms->SetPreroll(TRUE); - else ms->SetPreroll(FALSE); - }else { - ms->SetSyncPoint(FALSE); - ms->SetTime(NULL,NULL); - ms->SetMediaTime(NULL, NULL); - ms->SetPreroll(FALSE); - MessageBox(0,"here I'm","Hallo",0); - // 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); -} - -void AudioWin::ResetTimeOffsets() { - VideoWin *vw=(VideoWin*)Video::getInstance(); - return vw->ResetTimeOffsets(); -} - -#ifdef DEV -int AudioWin::test() -{ - return 0; -} -#endif +/* + 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 "audiowin.h" +#include "videowin.h" + + + + + +AudioWin::AudioWin() +{ + initted = 0; + firstsynched=false; + winvolume=0; + volume=20; + + + +} + +AudioWin::~AudioWin() +{ + + +} + +int AudioWin::init(UCHAR tstreamType) +{ + if (initted) return 0; + initted = 1; + return 1; +} + +int AudioWin::shutdown() +{ + if (!initted) return 0; + initted = 0; + return 1; +} + +int AudioWin::write(char *buf, int len) +{ + return 0; //write(fdAudio, buf, len); +} + +int AudioWin::setStreamType(UCHAR type) +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::setChannel() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::setSource() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::sync() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::play() +{ + if (!initted) return 0; + firstsynched=false; + + return 1; +} + +int AudioWin::stop() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::pause() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::unPause() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::reset() +{ + if (!initted) return 0; + return 1; +} + +int AudioWin::setVolume(int tvolume) +{ + // parameter: 0 for silence, 20 for full + if ((tvolume < 0) || (tvolume > 20)) return 0; + winvolume=((tvolume-20)*100*30)/20; + if (tvolume==0) winvolume=-10000; + ((VideoWin*)Video::getInstance())->SetAudioVolume(winvolume); + + + return 1; +} + +int AudioWin::mute() +{ + if (!initted) return 0; + ((VideoWin*)Video::getInstance())->SetAudioState(false); + ((VideoWin*)Video::getInstance())->SetAudioVolume(-10000); + return 1; +} + +int AudioWin::unMute() +{ + if (!initted) return 0; + ((VideoWin*)Video::getInstance())->SetAudioState(true); + ((VideoWin*)Video::getInstance())->SetAudioVolume(winvolume); + 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 *samplepos; + } + 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 *samplepos; + } + 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); + if (reftime1<0) ms->SetPreroll(TRUE); + else ms->SetPreroll(FALSE); + }else { + ms->SetSyncPoint(FALSE); + ms->SetTime(NULL,NULL); + ms->SetMediaTime(NULL, NULL); + ms->SetPreroll(FALSE); + MessageBox(0,"here I'm","Hallo",0); + // 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); +} + +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 1727b52..52690b5 100644 --- a/audiowin.h +++ b/audiowin.h @@ -1,64 +1,65 @@ -/* - 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 AUDIOWIN_H -#define AUDIOWIN_H - -#include "defines.h" -#include "log.h" -#include "audio.h" - -class AudioWin : public Audio -{ - public: - AudioWin(); - ~AudioWin(); - - int init(UCHAR streamType); - int shutdown(); - - int setStreamType(UCHAR streamType); - int setChannel(); - int setSource(); - int sync(); - int play(); - int stop(); - int pause(); - int unPause(); - int reset(); - int setVolume(int volume); - int mute(); - int unMute(); - int write(char *buf, int len); - - // 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; -#ifdef DEV - int test(); -#endif -}; - -#endif +/* + 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 AUDIOWIN_H +#define AUDIOWIN_H + +#include "defines.h" +#include "log.h" +#include "audio.h" + +class AudioWin : public Audio +{ + public: + AudioWin(); + ~AudioWin(); + + int init(UCHAR streamType); + int shutdown(); + + int setStreamType(UCHAR streamType); + int setChannel(); + int setSource(); + int sync(); + int play(); + int stop(); + int pause(); + int unPause(); + int reset(); + int setVolume(int volume); + int mute(); + int unMute(); + int write(char *buf, int len); + + // 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; + long winvolume; +#ifdef DEV + int test(); +#endif +}; + +#endif diff --git a/box.cc b/box.cc index a047615..0203155 100644 --- a/box.cc +++ b/box.cc @@ -171,7 +171,9 @@ void Box::drawPara(char* text, int x, int y, Colour& colour) textPos++; } - line[linePos++] = '\0'; +// line[linePos++] = '\0'; + if (linePos>=0) line[linePos++] = '\0'; //Here is the change + if (printLine || (linePos > 1)) // if some text was put in line { drawText(line, x, ypos, colour); diff --git a/command.cc b/command.cc index 6a9ac67..540a652 100644 --- a/command.cc +++ b/command.cc @@ -359,6 +359,9 @@ void Command::doStandby() VDR::getInstance()->disconnect(); Led::getInstance()->off(); isStandby = 1; +#ifdef WIN32 + stop(); //different behavoiur on windows, we exit +#endif } } diff --git a/osdwin.cc b/osdwin.cc index 2df6fe1..e3d04cf 100644 --- a/osdwin.cc +++ b/osdwin.cc @@ -218,8 +218,9 @@ void OsdWin::InternalRendering(LPDIRECT3DSURFACE9 present){ d3ddevice->StretchRect(present,&sourcerect,d3drtsurf ,&destrect,D3DTEXF_LINEAR); } } else { + VideoWin* video =(VideoWin*) Video::getInstance(); //Clear Background - d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0); + if (!video->isVideoOn()) d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0); } //Drawing the OSD if (d3ddevice->BeginScene()==D3D_OK) { @@ -308,3 +309,11 @@ void OsdWin::setExternalDriving(DsAllocator* dsall) { dsallocator=dsall; external_driving=true; } + +void OsdWin::Blank() { + WaitForSingleObject(event,INFINITE); + BeginPainting(); + d3ddevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0); + EndPainting(); +} + diff --git a/osdwin.h b/osdwin.h index c545126..ad0b89c 100644 --- a/osdwin.h +++ b/osdwin.h @@ -61,6 +61,7 @@ class OsdWin : public Osd void BeginPainting(); void EndPainting(); void setExternalDriving(DsAllocator* dsall); + void Blank(); private: LPDIRECT3D9 d3d; LPDIRECT3DDEVICE9 d3ddevice; diff --git a/player.cc b/player.cc index 731019b..4475fdc 100644 --- a/player.cc +++ b/player.cc @@ -372,7 +372,9 @@ void Player::toggleFastForwardInt() else { ffwd = true; +#ifndef WIN32 afeed.disable(); +#endif audio->systemMuteOn(); video->fastForward(); } @@ -399,7 +401,9 @@ void Player::toggleFastBackwardInt() else { fbwd = false; +#ifndef WIN32 afeed.disable(); +#endif audio->systemMuteOn(); threadStop(); diff --git a/remotewin.cc b/remotewin.cc index 1d6fbc3..c4ca8cb 100644 --- a/remotewin.cc +++ b/remotewin.cc @@ -211,3 +211,9 @@ void RemoteWin::Signal() { SetEvent(event); } +void RemoteWin::SendPower() +{ + curevent=POWER; + SetEvent(event); +} + diff --git a/remotewin.h b/remotewin.h index 4d12235..a4b11e4 100644 --- a/remotewin.h +++ b/remotewin.h @@ -1,58 +1,60 @@ -/* - 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 REMOTEWIN_H -#define REMOTEWIN_H - -#include - -#include "defines.h" -#include "log.h" -#include "remote.h" - -#define _WIN32_WINNT 0x501 -#include -#include - - - -class RemoteWin : public Remote -{ - public: - RemoteWin(); - ~RemoteWin(); - - int init(char *devName); - int shutdown(); - 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 +/* + 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 REMOTEWIN_H +#define REMOTEWIN_H + +#include + +#include "defines.h" +#include "log.h" +#include "remote.h" + +#define _WIN32_WINNT 0x501 +#include +#include + + + +class RemoteWin : public Remote +{ + public: + RemoteWin(); + ~RemoteWin(); + + int init(char *devName); + int shutdown(); + int getDevice(); + UCHAR getButtonPress(int how); + void clearBuffer(); + void Signal(); + int ReceiveButtonVK(UINT button);//Windows Message from WND_PROC + int ReceiveButtonAP(UINT button); + void SendPower(); + + private: + int initted; + bool signal; + UCHAR curevent; + HANDLE event; +}; + +#endif + diff --git a/stream.cc b/stream.cc index fc8c696..68232ab 100644 --- a/stream.cc +++ b/stream.cc @@ -36,7 +36,14 @@ Stream::~Stream() void Stream::shutdown() { - if (initted) free(outbuf); + if (initted) { + free(outbuf); +#ifdef NEW_DEMUXER +#ifdef WIN32 + CloseHandle(mutex); +#endif +#endif + } initted = 0; } @@ -51,13 +58,22 @@ int Stream::init(DrainTarget* tdt, int bufsize) bufferTail = 0; bufferMark = -1; initted = 1; +#ifdef NEW_DEMUXER +#ifndef WIN32 + pthread_mutex_init(&mutex, NULL); +#else + mutex=CreateMutex(NULL,FALSE,NULL); +#endif +#endif return 1; } void Stream::flush() { #ifdef NEW_DEMUXER + lock(); mediapackets.clear(); + unLock(); if (draintarget) draintarget->ResetTimeOffsets(); #endif bufferHead = 0; @@ -141,7 +157,9 @@ int Stream::put(UCHAR* inbuf, int len,ULLONG curpos) bufferHead += len; ret = len; newPacket.pos_buffer=head; + lock(); mediapackets.push_front(newPacket); + unLock(); } } else if (len <= bufferSize - head) @@ -154,7 +172,9 @@ int Stream::put(UCHAR* inbuf, int len,ULLONG curpos) bufferHead += len; newPacket.pos_buffer=head; + lock(); mediapackets.push_front(newPacket); + unLock(); ret = len; } @@ -165,7 +185,9 @@ int Stream::put(UCHAR* inbuf, int len,ULLONG curpos) bufferHead = len; ret = len; newPacket.pos_buffer=0; + lock(); mediapackets.push_front(newPacket); + unLock(); } return ret; } @@ -239,15 +261,19 @@ int Stream::drain() int tail = bufferTail; int mark = bufferMark; if (mark == -1 && tail > head) mark = bufferSize; + lock(); MediaPacket cur_mp=mediapackets.back(); + unLock(); written=0; - written=dt->DeliverMediaSample(cur_mp,outbuf,&cur_packet_pos); + written=draintarget->DeliverMediaSample(cur_mp,outbuf,&cur_packet_pos); ret+=written; if (cur_packet_pos==cur_mp.length) { cur_packet_pos=0; + lock(); mediapackets.pop_back(); + unLock(); if ((((ULONG)tail)+cur_mp.length) < ((ULONG)mark)) { bufferTail=tail+cur_mp.length; } else { @@ -260,4 +286,25 @@ int Stream::drain() return ret; } +void Stream::lock() +{ +#ifndef WIN32 + pthread_mutex_lock(&mutex); + logger->log("Player", Log::DEBUG, "LOCKED"); + +#else + WaitForSingleObject(mutex, INFINITE ); +#endif +} + +void Stream::unLock() +{ +#ifndef WIN32 + logger->log("Player", Log::DEBUG, "UNLOCKING"); + pthread_mutex_unlock(&mutex); +#else + ReleaseMutex(mutex); +#endif +} + #endif diff --git a/stream.h b/stream.h index 33d97c0..db7e80c 100644 --- a/stream.h +++ b/stream.h @@ -24,6 +24,9 @@ #include #ifndef WIN32 #include +#else +#include +#include #endif #include #include "defines.h" @@ -51,6 +54,13 @@ class Stream #ifdef NEW_DEMUXER MediaPacketList mediapackets; UINT cur_packet_pos; +#ifndef WIN32 + pthread_mutex_t mutex; +#else + HANDLE mutex; +#endif + void lock(); + void unLock(); #endif DrainTarget* draintarget; diff --git a/surface.cc b/surface.cc index 5339171..04c1d5a 100644 --- a/surface.cc +++ b/surface.cc @@ -110,7 +110,7 @@ int Surface::drawTextCentre(char* text, int x, int y, ULONG rgba) int Surface::getCharWidth(char c) { - return font->width[c]; + return font->width[(unsigned char) c]; } int Surface::getFontHeight() diff --git a/vdr.cc b/vdr.cc index b89e58d..0efd189 100644 --- a/vdr.cc +++ b/vdr.cc @@ -351,7 +351,10 @@ bool VDR::getRecordingsList(RecMan* recman) return false; } - recman->setStats(extractULONG(), extractULONG(), extractULONG()); + ULONG totalSpace = extractULONG(); + ULONG freeSpace = extractULONG(); + ULONG percent = extractULONG(); + recman->setStats(totalSpace, freeSpace, percent); ULONG start; char* name; diff --git a/videowin.cc b/videowin.cc index 3462f6c..487c019 100644 --- a/videowin.cc +++ b/videowin.cc @@ -1,691 +1,714 @@ -/* - 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 "videowin.h" -#include "log.h" -#include "dssourcefilter.h" -#include "dsallocator.h" -#include "vdr.h" - -void AdjustWindow(); - - - -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; - offsetaudionotset=true; - startoffset=0; - lastrefaudiotime=0; - lastrefvideotime=0; - lastreftimeBYTE=0; - lastreftimeRT=0; - firstsynched=false; - cur_audio_media_sample=NULL; - cur_video_media_sample=NULL; - videoon=true; - audioon=true; - pseudotvsize=0; - videoposx=0; - videoposy=0; - - - -} - -VideoWin::~VideoWin() -{ - CleanupDS(); - CloseHandle(filtermutex); - - - - instance = NULL; -} - -int VideoWin::init(UCHAR tformat) -{ - if (initted) return 0; - - initted = 1; - tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV - videoposx=0; - videoposy=0; - - if (!setFormat(tformat)){ shutdown(); return 0; } - return 1; -} - -int VideoWin::setTVsize(UCHAR ttvsize) -{ - pseudotvsize=ttvsize; - return 1; -} - -int VideoWin::setDefaultAspect() -{ - return setAspectRatio(Video::ASPECT4X3); -} - -int VideoWin::shutdown() -{ - if (!initted) return 0; - initted = 0; - return 1; -} - -int VideoWin::setFormat(UCHAR tformat) -{ - 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; -} - -int VideoWin::setConnection(UCHAR tconnection) -{ - if (!initted) return 0; - if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0; - connection = tconnection; - - return 1; -} - -int VideoWin::setAspectRatio(UCHAR taspectRatio) -{ - if (!initted) return 0; - if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; - aspectRatio = taspectRatio; - AdjustWindow(); - return 1; -} - -int VideoWin::setMode(UCHAR tmode) -{ - if (!initted) return 0; - - //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; - videoposx=0; - videoposy=0; - AdjustWindow(); - - return 1; -} - -int VideoWin::signalOff() -{ - return 1; -} - -int VideoWin::signalOn() -{ - return 1; -} - -int VideoWin::setSource() -{ - if (!initted) return 0; - - return 1; -} - -int VideoWin::setPosition(int x, int y) -{ - if (!initted) return 0; - if (mode==QUARTER || mode==EIGHTH) { - videoposx=x; - videoposy=y; - } - return 1; -} - -int VideoWin::sync() -{ - if (!initted) return 0; - - 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); - 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 (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) { - //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; -} - -int VideoWin::stop() -{ - if (!initted) return 0; - - CleanupDS(); - - - return 1; -} - -int VideoWin::reset() -{ - if (!initted) return 0; - videoposx=0; - videoposy=0; - - 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; -} - -int VideoWin::fastForward() -{ - if (!initted) return 0; - return 1; -} - -int VideoWin::unFastForward() -{ - if (!initted) return 0; - return 1; -} - -int VideoWin::attachFrameBuffer() -{ - if (!initted) return 0; - return 1; -} - -int VideoWin::blank(void) -{ - return 1; -} - -ULLONG VideoWin::getCurrentTimestamp() -{ - 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) -{ - if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25); - 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); - 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 (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(); - 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); - 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->SetPreroll(FALSE); - - // 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; - -} -void VideoWin::ResetTimeOffsets() { - offsetnotset=true; //called from demuxer - offsetvideonotset=true; - offsetaudionotset=true; - startoffset=0; - lastrefaudiotime=0; - lastrefvideotime=0; - lastreftimeBYTE=0; - lastreftimeRT=0; - - -} - - -#ifdef DEV -int VideoWin::test() -{ - return 0; -} - -int VideoWin::test2() -{ - return 0; -} -#endif +/* + 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 "videowin.h" +#include "log.h" +#include "dssourcefilter.h" +#include "dsallocator.h" +#include "vdr.h" +#include "osdwin.h" + +void AdjustWindow(); + + + +VideoWin::VideoWin() +{ + dsgraphbuilder=NULL; + dsmediacontrol=NULL; + dsvmrrenderer=NULL; + dsrefclock=NULL; + dsmediafilter=NULL; + dsbasicaudio=NULL; + sourcefilter=NULL; + allocatorvmr=NULL; + cr_time=0; + dsvmrsurfnotify=NULL; + filtermutex=CreateMutex(NULL,FALSE,NULL); + offsetnotset=true; + offsetvideonotset=true; + offsetaudionotset=true; + startoffset=0; + lastrefaudiotime=0; + lastrefvideotime=0; + lastreftimeBYTE=0; + lastreftimeRT=0; + firstsynched=false; + cur_audio_media_sample=NULL; + cur_video_media_sample=NULL; + videoon=true; + audioon=true; + pseudotvsize=0; + videoposx=0; + videoposy=0; + + + +} + +VideoWin::~VideoWin() +{ + CleanupDS(); + CloseHandle(filtermutex); + + + + instance = NULL; +} + +int VideoWin::init(UCHAR tformat) +{ + if (initted) return 0; + + initted = 1; + tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV + videoposx=0; + videoposy=0; + + if (!setFormat(tformat)){ shutdown(); return 0; } + return 1; +} + +int VideoWin::setTVsize(UCHAR ttvsize) +{ + pseudotvsize=ttvsize; + return 1; +} + +int VideoWin::setDefaultAspect() +{ + return setAspectRatio(Video::ASPECT4X3); +} + +int VideoWin::shutdown() +{ + if (!initted) return 0; + initted = 0; + return 1; +} + +int VideoWin::setFormat(UCHAR tformat) +{ + 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; +} + +int VideoWin::setConnection(UCHAR tconnection) +{ + if (!initted) return 0; + if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0; + connection = tconnection; + + return 1; +} + +int VideoWin::setAspectRatio(UCHAR taspectRatio) +{ + if (!initted) return 0; + if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0; + aspectRatio = taspectRatio; + AdjustWindow(); + return 1; +} + +int VideoWin::setMode(UCHAR tmode) +{ + if (!initted) return 0; + + //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; + videoposx=0; + videoposy=0; + AdjustWindow(); + + return 1; +} + +int VideoWin::signalOff() +{ + return 1; +} + +int VideoWin::signalOn() +{ + return 1; +} + +int VideoWin::setSource() +{ + if (!initted) return 0; + + return 1; +} + +int VideoWin::setPosition(int x, int y) +{ + if (!initted) return 0; + if (mode==QUARTER || mode==EIGHTH) { + videoposx=x; + videoposy=y; + } + return 1; +} + +int VideoWin::sync() +{ + if (!initted) return 0; + + 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); + 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 (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) { + //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); + dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio); + + dsmediacontrol->Run(); + ReleaseMutex(filtermutex); + return 1; +} + +int VideoWin::stop() +{ + if (!initted) return 0; + + CleanupDS(); + + + return 1; +} + +int VideoWin::reset() +{ + if (!initted) return 0; + videoposx=0; + videoposy=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; +} + +int VideoWin::fastForward() +{ + if (!initted) return 0; + + return 1; +} + +int VideoWin::unFastForward() +{ + if (!initted) return 0; + + return 1; +} + +int VideoWin::attachFrameBuffer() +{ + if (!initted) return 0; + return 1; +} + +int VideoWin::blank(void) +{ + ((OsdWin*)Osd::getInstance())->Blank(); + return 1; +} + +ULLONG VideoWin::getCurrentTimestamp() +{ + REFERENCE_TIME startoffset; + REFERENCE_TIME ncr_time; + + if (!dsrefclock || !sourcefilter) return 0; + FILTER_STATE state; + sourcefilter->GetState(10,&state); + + if (state==State_Running) dsrefclock->GetTime(&cr_time); + ncr_time=cr_time; + startoffset=sourcefilter->getStartOffset(); + ncr_time-=startoffset; + ncr_time-=lastreftimeRT; + ULLONG result=frameNumberToTimecode( + VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE)); + result+=(ULLONG)(ncr_time/10000LL*90LL); + return result; + +} + +ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode) +{ + if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25); + 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); + 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 (dsbasicaudio) { + dsbasicaudio->Release(); + dsbasicaudio=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(); + 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); + 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->SetPreroll(FALSE); + + // 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; + +} +void VideoWin::ResetTimeOffsets() { + offsetnotset=true; //called from demuxer + offsetvideonotset=true; + offsetaudionotset=true; + startoffset=0; + lastrefaudiotime=0; + lastrefvideotime=0; + lastreftimeBYTE=0; + lastreftimeRT=0; + + +} + +void VideoWin::SetAudioVolume(long volume) +{ + if (dsbasicaudio) dsbasicaudio->put_Volume(volume); +} + +#ifdef DEV +int VideoWin::test() +{ + return 0; +} + +int VideoWin::test2() +{ + return 0; +} +#endif diff --git a/videowin.h b/videowin.h index 5e01c3d..c6b6db8 100644 --- a/videowin.h +++ b/videowin.h @@ -1,135 +1,140 @@ -/* - 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 VIDEOWIN_H -#define VIDEOWIN_H - -#include -#include -#include -#include -#include -#include - -#include "defines.h" -#include "video.h" - -#define DS_DEBUG - -class DsSourceFilter; -class DsAllocator; - -class VideoWin : public Video -{ - public: - VideoWin(); - ~VideoWin(); - - int init(UCHAR format); - int shutdown(); - - int setFormat(UCHAR format); - int setConnection(UCHAR connection); - int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching - 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(); - int setPosition(int x, int y); - int sync(); - int play(); - int stop(); - int pause(); - int unPause(); - int fastForward(); - int unFastForward(); - int reset(); - int blank(); - int signalOn(); - int signalOff(); - int attachFrameBuffer(); // What does this do? - ULONG timecodeToFrameNumber(ULLONG timecode); - ULLONG frameNumberToTimecode(ULONG framenumber); - 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(); - - 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;}; - - void turnVideoOn(){videoon=true;}; - void turnVideoOff(){videoon=false;}; - - unsigned int getPosx() {return videoposx;}; - unsigned int getPosy() {return videoposy;}; - -#ifdef DEV - int test(); - int test2(); -#endif -private: - IMediaControl* dsmediacontrol; - 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; - bool offsetvideonotset; - bool offsetaudionotset; - long long startoffset; - long long lastrefvideotime; - long long lastrefaudiotime; - - bool firstsynched; - bool audioon; - bool videoon; - UCHAR pseudotvsize; - REFERENCE_TIME lastreftimeRT; - ULLONG lastreftimeBYTE; - unsigned int videoposx; - unsigned int videoposy; -#ifdef DS_DEBUG - DWORD graphidentifier; -#endif -}; - -#endif +/* + 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 VIDEOWIN_H +#define VIDEOWIN_H + +#include +#include +#include +#include +#include +#include + +#include "defines.h" +#include "video.h" + +//#define DS_DEBUG + +class DsSourceFilter; +class DsAllocator; + +class VideoWin : public Video +{ + public: + VideoWin(); + ~VideoWin(); + + int init(UCHAR format); + int shutdown(); + + int setFormat(UCHAR format); + int setConnection(UCHAR connection); + int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching + 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(); + int setPosition(int x, int y); + int sync(); + int play(); + int stop(); + int pause(); + int unPause(); + int fastForward(); + int unFastForward(); + int reset(); + int blank(); + int signalOn(); + int signalOff(); + int attachFrameBuffer(); // What does this do? + ULONG timecodeToFrameNumber(ULLONG timecode); + ULLONG frameNumberToTimecode(ULONG framenumber); + 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(); + + 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;}; + void SetAudioVolume(long volume); + + void turnVideoOn(){videoon=true;}; + void turnVideoOff(){videoon=false;}; + + unsigned int getPosx() {return videoposx;}; + unsigned int getPosy() {return videoposy;}; + bool isVideoOn() {return videoon;}; + +#ifdef DEV + int test(); + int test2(); +#endif +private: + IMediaControl* dsmediacontrol; + + IGraphBuilder* dsgraphbuilder; + IMediaSample* cur_audio_media_sample; + IMediaSample* cur_video_media_sample; + IBaseFilter* dsvmrrenderer; + IVMRSurfaceAllocatorNotify9 *dsvmrsurfnotify; + IReferenceClock *dsrefclock; + IMediaFilter* dsmediafilter; + IBasicAudio* dsbasicaudio; + REFERENCE_TIME cr_time; + + DsSourceFilter* sourcefilter; + DsAllocator* allocatorvmr; + 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; + UCHAR pseudotvsize; + REFERENCE_TIME lastreftimeRT; + ULLONG lastreftimeBYTE; + unsigned int videoposx; + unsigned int videoposy; +#ifdef DS_DEBUG + DWORD graphidentifier; +#endif +}; + +#endif diff --git a/winmain.cc b/winmain.cc index e6e9459..4bd2d31 100644 --- a/winmain.cc +++ b/winmain.cc @@ -447,8 +447,8 @@ LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam) 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(); + + ((RemoteWin*)Remote::getInstance())->SendPower(); PostQuitMessage(0); }break; case WM_SIZING: { @@ -506,6 +506,14 @@ LONG FAR PASCAL WindowProc(HWND wind, UINT msg, WPARAM wparam, LPARAM lparam) return DefWindowProc(wind, msg, wparam, lparam); } break; + case WM_SYSCOMMAND: + if (wparam==SC_MAXIMIZE) { + ToggleFullscreen(); + return 0; + } else { + return DefWindowProc(wind,msg,wparam, lparam); + } + break; default: return DefWindowProc(wind, msg, wparam, lparam); } -- 2.39.2