-/*
- 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
+/*\r
+ Copyright 2004-2005 Chris Tallon\r
+\r
+ This file is part of VOMP.\r
+\r
+ VOMP is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ VOMP is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with VOMP; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+*/\r
+\r
+#include "audiowin.h"\r
+#include "videowin.h"\r
+\r
+\r
+\r
+\r
+\r
+AudioWin::AudioWin()\r
+{\r
+ initted = 0;\r
+ firstsynched=false;\r
+ winvolume=0;\r
+ volume=20;\r
+\r
+\r
+\r
+}\r
+\r
+AudioWin::~AudioWin()\r
+{\r
+\r
+\r
+}\r
+\r
+int AudioWin::init(UCHAR tstreamType)\r
+{\r
+ if (initted) return 0;\r
+ initted = 1;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::shutdown()\r
+{\r
+ if (!initted) return 0;\r
+ initted = 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::write(char *buf, int len)\r
+{\r
+ return 0; //write(fdAudio, buf, len);\r
+}\r
+\r
+int AudioWin::setStreamType(UCHAR type)\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::setChannel()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::setSource()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::sync()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::play()\r
+{\r
+ if (!initted) return 0;\r
+ firstsynched=false;\r
+\r
+ return 1;\r
+}\r
+\r
+int AudioWin::stop()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::pause()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::unPause()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::reset()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int AudioWin::setVolume(int tvolume)\r
+{\r
+ // parameter: 0 for silence, 20 for full\r
+ if ((tvolume < 0) || (tvolume > 20)) return 0;\r
+ winvolume=((tvolume-20)*100*30)/20;\r
+ if (tvolume==0) winvolume=-10000;\r
+ ((VideoWin*)Video::getInstance())->SetAudioVolume(winvolume);\r
+\r
+\r
+ return 1;\r
+}\r
+\r
+int AudioWin::mute()\r
+{\r
+ if (!initted) return 0;\r
+ ((VideoWin*)Video::getInstance())->SetAudioState(false);\r
+ ((VideoWin*)Video::getInstance())->SetAudioVolume(-10000);\r
+ return 1;\r
+}\r
+\r
+int AudioWin::unMute()\r
+{\r
+ if (!initted) return 0;\r
+ ((VideoWin*)Video::getInstance())->SetAudioState(true);\r
+ ((VideoWin*)Video::getInstance())->SetAudioVolume(winvolume);\r
+ return 1;\r
+}\r
+\r
+UINT AudioWin::DeliverMediaSample(MediaPacket packet,\r
+ UCHAR* buffer,\r
+ UINT *samplepos)\r
+{\r
+ /*First Check, if we have an audio sample*/\r
+ VideoWin *vw=(VideoWin*)Video::getInstance();\r
+ IMediaSample* ms=NULL;\r
+ REFERENCE_TIME reftime1=0;\r
+ REFERENCE_TIME reftime2=0;\r
+\r
+ UINT headerstrip=0;\r
+ if (packet.disconti) {\r
+ firstsynched=false;\r
+ vw->DeliverVideoMediaSample();\r
+ }\r
+\r
+\r
+\r
+ /*Inspect PES-Header */\r
+/* UINT header_length=buffer[(packet.pos_buffer+8)%bufferlength]+8/*is this right*;\r
+*/\r
+ if (*samplepos==0) {//stripheader\r
+ headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;\r
+ *samplepos+=headerstrip;\r
+ if ( packet.synched ) {\r
+ vw->DeliverAudioMediaSample();//write out old data\r
+ /* if (packet.presentation_time<0) { //Preroll?\r
+ *samplepos=packet.length;//if we have not processed at least one\r
+ return packet.length;//synched packet ignore it!\r
+ }*/\r
+\r
+ reftime1=packet.presentation_time;\r
+ reftime2=reftime1+1;\r
+ firstsynched=true;\r
+ } else {\r
+ if (!firstsynched) {//\r
+ *samplepos=packet.length;//if we have not processed at least one\r
+ return packet.length;//synched packet ignore it!\r
+ }\r
+ }\r
+ }\r
+ BYTE *ms_buf;\r
+ UINT ms_length;\r
+ UINT ms_pos;\r
+ UINT haveToCopy;\r
+ if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample\r
+ //samplepos=0;\r
+ MILLISLEEP(10);\r
+ return *samplepos;\r
+ }\r
+ ms_pos=ms->GetActualDataLength();\r
+ ms_length=ms->GetSize();\r
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);\r
+ if ((ms_length-ms_pos)<1) {\r
+ vw->DeliverAudioMediaSample(); //we are full!\r
+ if (!vw->getCurrentAudioMediaSample(&ms) || ms==NULL) {// get the current sample\r
+ //samplepos=0;\r
+ MILLISLEEP(10);\r
+ return *samplepos;\r
+ }\r
+ ms_pos=ms->GetActualDataLength();\r
+ ms_length=ms->GetSize();\r
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);\r
+ }\r
+ ms->GetPointer(&ms_buf);\r
+\r
+ if (ms_pos==0) {//will only be changed on first packet\r
+ if (packet.disconti) {\r
+ ms->SetDiscontinuity(TRUE);\r
+ } else {\r
+ ms->SetDiscontinuity(FALSE);\r
+ }\r
+ if (packet.synched) {\r
+ ms->SetSyncPoint(TRUE);\r
+ ms->SetTime(&reftime1,&reftime2);\r
+\r
+ //ms->SetTime(NULL,NULL);\r
+ ms->SetMediaTime(NULL, NULL);\r
+ if (reftime1<0) ms->SetPreroll(TRUE);\r
+ else ms->SetPreroll(FALSE);\r
+ }else {\r
+ ms->SetSyncPoint(FALSE);\r
+ ms->SetTime(NULL,NULL);\r
+ ms->SetMediaTime(NULL, NULL);\r
+ ms->SetPreroll(FALSE);\r
+ MessageBox(0,"here I'm","Hallo",0);\r
+ // ms->SetSyncPoint(TRUE);\r
+ }\r
+ }\r
+\r
+\r
+ memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);\r
+ ms->SetActualDataLength(haveToCopy+ms_pos);\r
+\r
+ *samplepos+=haveToCopy;\r
+\r
+ return haveToCopy+headerstrip;\r
+\r
+}\r
+\r
+long long AudioWin::SetStartOffset(long long curreftime, bool *rsync){\r
+ VideoWin *vw=(VideoWin*)Video::getInstance();\r
+ return vw->SetStartAudioOffset(curreftime,rsync);\r
+}\r
+\r
+void AudioWin::ResetTimeOffsets() {\r
+ VideoWin *vw=(VideoWin*)Video::getInstance();\r
+ return vw->ResetTimeOffsets();\r
+}\r
+\r
+#ifdef DEV\r
+int AudioWin::test()\r
+{\r
+ return 0;\r
+}\r
+#endif\r
\r
-/*
- 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
+/*\r
+ Copyright 2004-2005 Chris Tallon\r
+\r
+ This file is part of VOMP.\r
+\r
+ VOMP is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ VOMP is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with VOMP; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+*/\r
+\r
+#include "videowin.h"\r
+#include "log.h"\r
+#include "dssourcefilter.h"\r
+#include "dsallocator.h"\r
+#include "vdr.h"\r
+#include "osdwin.h"\r
+\r
+void AdjustWindow();\r
+\r
+\r
+\r
+VideoWin::VideoWin()\r
+{\r
+ dsgraphbuilder=NULL;\r
+ dsmediacontrol=NULL;\r
+ dsvmrrenderer=NULL;\r
+ dsrefclock=NULL;\r
+ dsmediafilter=NULL;\r
+ dsbasicaudio=NULL;\r
+ sourcefilter=NULL;\r
+ allocatorvmr=NULL;\r
+ cr_time=0;\r
+ dsvmrsurfnotify=NULL;\r
+ filtermutex=CreateMutex(NULL,FALSE,NULL);\r
+ offsetnotset=true;\r
+ offsetvideonotset=true;\r
+ offsetaudionotset=true;\r
+ startoffset=0;\r
+ lastrefaudiotime=0;\r
+ lastrefvideotime=0;\r
+ lastreftimeBYTE=0;\r
+ lastreftimeRT=0;\r
+ firstsynched=false;\r
+ cur_audio_media_sample=NULL;\r
+ cur_video_media_sample=NULL;\r
+ videoon=true;\r
+ audioon=true;\r
+ pseudotvsize=0;\r
+ videoposx=0;\r
+ videoposy=0;\r
+\r
+\r
+\r
+}\r
+\r
+VideoWin::~VideoWin()\r
+{\r
+ CleanupDS();\r
+ CloseHandle(filtermutex);\r
+\r
+\r
+\r
+ instance = NULL;\r
+}\r
+\r
+int VideoWin::init(UCHAR tformat)\r
+{\r
+ if (initted) return 0;\r
+\r
+ initted = 1;\r
+ tvsize=Video::ASPECT16X9; //Internally Vomp should think we are a 16:9 TV\r
+ videoposx=0;\r
+ videoposy=0;\r
+\r
+ if (!setFormat(tformat)){ shutdown(); return 0; }\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setTVsize(UCHAR ttvsize)\r
+{\r
+ pseudotvsize=ttvsize;\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setDefaultAspect()\r
+{\r
+ return setAspectRatio(Video::ASPECT4X3);\r
+}\r
+\r
+int VideoWin::shutdown()\r
+{\r
+ if (!initted) return 0;\r
+ initted = 0;\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setFormat(UCHAR tformat)\r
+{\r
+ if (!initted) return 0;\r
+ if ((tformat != PAL) && (tformat != NTSC)) return 0;\r
+ format = tformat;\r
+ if (format == NTSC)\r
+ {\r
+ screenWidth = 720;\r
+ screenHeight = 480;\r
+ }\r
+ if (format == PAL)\r
+ {\r
+ screenWidth = 720;\r
+ screenHeight = 576;\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setConnection(UCHAR tconnection)\r
+{\r
+ if (!initted) return 0;\r
+ if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;\r
+ connection = tconnection;\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setAspectRatio(UCHAR taspectRatio)\r
+{\r
+ if (!initted) return 0;\r
+ if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;\r
+ aspectRatio = taspectRatio;\r
+ AdjustWindow();\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setMode(UCHAR tmode)\r
+{\r
+ if (!initted) return 0;\r
+\r
+ //if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode\r
+\r
+ if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)\r
+ && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;\r
+ mode = tmode;\r
+ videoposx=0;\r
+ videoposy=0;\r
+ AdjustWindow();\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::signalOff()\r
+{\r
+ return 1;\r
+}\r
+\r
+int VideoWin::signalOn()\r
+{\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setSource()\r
+{\r
+ if (!initted) return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::setPosition(int x, int y)\r
+{\r
+ if (!initted) return 0;\r
+ if (mode==QUARTER || mode==EIGHTH) {\r
+ videoposx=x;\r
+ videoposy=y;\r
+ }\r
+ return 1;\r
+}\r
+\r
+int VideoWin::sync()\r
+{\r
+ if (!initted) return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+#ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions\r
+#include "dshelper.h"\r
+#endif\r
+\r
+#define DO_VIDEO\r
+\r
+int VideoWin::play()\r
+{\r
+ if (!initted) return 0;\r
+\r
+ //Build filter graph\r
+ HRESULT hres;\r
+\r
+ if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,\r
+ IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {\r
+ return 0;\r
+ }\r
+ #ifdef DS_DEBUG\r
+ AddToRot(dsgraphbuilder,&graphidentifier);\r
+ #endif\r
+ //This is just a try to see if building the graph works\r
+// dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);\r
+ //So this is the real code, this prevents the feeder from calling noexisting objects!\r
+ WaitForSingleObject(filtermutex,INFINITE);\r
+ firstsynched=false;\r
+ sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data\r
+ // to DirectShow\r
+ if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {\r
+ Log::getInstance()->log("VideoWin", Log::WARN , "Failed adding Vomp Source Filter!");\r
+ CleanupDS();\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ //if (audioon) {\r
+ if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(0)/*audio*/)!=S_OK) {\r
+ Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering audio!");\r
+ CleanupDS();\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ //}\r
+#ifdef DO_VIDEO\r
+ if (videoon) {\r
+ //We alloc the vmr9 as next step\r
+ if (hres=CoCreateInstance(CLSID_VideoMixingRenderer9,0,\r
+ CLSCTX_INPROC_SERVER,IID_IBaseFilter,(void**) &dsvmrrenderer)!=S_OK) {\r
+ Log::getInstance()->log("VideoWin", Log::WARN ,"Failed creating VMR9 renderer!");\r
+ CleanupDS();\r
+ ReleaseMutex(filtermutex);\r
+ }\r
+ /*VMR 9 stuff**/\r
+ if (hres=dsgraphbuilder->AddFilter(dsvmrrenderer,L"VMR9")!=S_OK) {\r
+ CleanupDS();\r
+ Log::getInstance()->log("VideoWin", Log::WARN ,"Failed adding VMR9 renderer!");\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ IVMRFilterConfig9* vmrfilconfig;\r
+ if (dsvmrrenderer->QueryInterface(IID_IVMRFilterConfig9,(void**)&vmrfilconfig)!=S_OK) {\r
+ CleanupDS();\r
+ Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Filterconfig interface!");\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ vmrfilconfig->SetRenderingMode(VMR9Mode_Renderless);\r
+ vmrfilconfig->Release();\r
+\r
+ if (dsvmrrenderer->QueryInterface(IID_IVMRSurfaceAllocatorNotify9,(void**)& dsvmrsurfnotify)!=S_OK) {\r
+ CleanupDS();\r
+ Log::getInstance()->log("VideoWin", Log::WARN ,"Failed getting VMR9 Surface Allocator interface!");\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ allocatorvmr=new DsAllocator();\r
+ dsvmrsurfnotify->AdviseSurfaceAllocator(NULL,allocatorvmr);\r
+ allocatorvmr->AdviseNotify(dsvmrsurfnotify);\r
+\r
+\r
+\r
+ /*VMR 9 stuff end */\r
+ IFilterGraph2*fg2=NULL;\r
+ if (dsgraphbuilder->QueryInterface(IID_IFilterGraph2,(void**)&fg2)!=S_OK) {\r
+ Log::getInstance()->log("VideoWin", Log::WARN , "Failed querying for FilterGraph2 Interface!");\r
+ CleanupDS();\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ if (hres=fg2->RenderEx(sourcefilter->GetPin(1)/*video*/,\r
+ AM_RENDEREX_RENDERTOEXISTINGRENDERERS,NULL)!=S_OK) {\r
+ Log::getInstance()->log("VideoWin", Log::WARN , "Failed rendering Video!");\r
+ CleanupDS();\r
+ ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ }\r
+#endif\r
+ if (hres=CoCreateInstance(CLSID_SystemClock,NULL,CLSCTX_INPROC_SERVER,\r
+ IID_IReferenceClock,(void**)&dsrefclock)!=S_OK) {\r
+ return 0;\r
+ }\r
+\r
+ dsgraphbuilder->QueryInterface(IID_IMediaFilter,(void **) &dsmediafilter);\r
+ dsmediafilter->SetSyncSource(dsrefclock);\r
+\r
+ dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);\r
+ dsgraphbuilder->QueryInterface(IID_IBasicAudio,(void **) &dsbasicaudio); \r
+\r
+ dsmediacontrol->Run();\r
+ ReleaseMutex(filtermutex);\r
+ return 1;\r
+}\r
+\r
+int VideoWin::stop()\r
+{\r
+ if (!initted) return 0;\r
+\r
+ CleanupDS();\r
+\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::reset()\r
+{\r
+ if (!initted) return 0;\r
+ videoposx=0;\r
+ videoposy=0;\r
+ CleanupDS();\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::pause()\r
+{\r
+ if (!initted) return 0;\r
+ if (dsmediacontrol) dsmediacontrol->Pause();\r
+ return 1;\r
+}\r
+\r
+int VideoWin::unPause() // FIXME get rid - same as play!!\r
+{//No on windows this is not the same, I don't get rid of!\r
+ if (!initted) return 0;\r
+ if (dsmediacontrol) dsmediacontrol->Run();\r
+ return 1;\r
+}\r
+\r
+int VideoWin::fastForward()\r
+{\r
+ if (!initted) return 0;\r
+\r
+ return 1;\r
+}\r
+\r
+int VideoWin::unFastForward()\r
+{\r
+ if (!initted) return 0;\r
+ \r
+ return 1;\r
+}\r
+\r
+int VideoWin::attachFrameBuffer()\r
+{\r
+ if (!initted) return 0;\r
+ return 1;\r
+}\r
+\r
+int VideoWin::blank(void)\r
+{\r
+ ((OsdWin*)Osd::getInstance())->Blank();\r
+ return 1;\r
+}\r
+\r
+ULLONG VideoWin::getCurrentTimestamp()\r
+{\r
+ REFERENCE_TIME startoffset;\r
+ REFERENCE_TIME ncr_time;\r
+\r
+ if (!dsrefclock || !sourcefilter) return 0;\r
+ FILTER_STATE state;\r
+ sourcefilter->GetState(10,&state);\r
+\r
+ if (state==State_Running) dsrefclock->GetTime(&cr_time);\r
+ ncr_time=cr_time;\r
+ startoffset=sourcefilter->getStartOffset();\r
+ ncr_time-=startoffset;\r
+ ncr_time-=lastreftimeRT;\r
+ ULLONG result=frameNumberToTimecode(\r
+ VDR::getInstance()->frameNumberFromPosition(lastreftimeBYTE));\r
+ result+=(ULLONG)(ncr_time/10000LL*90LL);\r
+ return result;\r
+\r
+}\r
+\r
+ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)\r
+{\r
+ if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);\r
+ else return (ULONG)(((double)timecode / (double)90000) * (double)30);\r
+}\r
+\r
+ULLONG VideoWin::frameNumberToTimecode(ULONG framenumber)\r
+{\r
+ if (format == PAL) return (ULLONG)(((double)framenumber * (double)90000) / (double)25);\r
+ else return (ULLONG)(((double)framenumber * (double)90000) / (double)30);\r
+}\r
+\r
+void VideoWin::CleanupDS()\r
+{\r
+ WaitForSingleObject(filtermutex,INFINITE);\r
+ if (cur_audio_media_sample) {\r
+ cur_audio_media_sample->Release();\r
+ cur_audio_media_sample=NULL;\r
+ }\r
+ if (cur_video_media_sample) {\r
+ cur_video_media_sample->Release();\r
+ cur_video_media_sample=NULL;\r
+ }\r
+ if (dsbasicaudio) {\r
+ dsbasicaudio->Release();\r
+ dsbasicaudio=NULL;\r
+ }\r
+ if (dsvmrsurfnotify) {\r
+ dsvmrsurfnotify->Release();\r
+ dsvmrsurfnotify=NULL;\r
+ }\r
+ if (dsvmrrenderer) {\r
+ dsvmrrenderer->Release();\r
+ dsvmrrenderer=NULL;\r
+ }\r
+\r
+ if (allocatorvmr) {\r
+ allocatorvmr->Release();\r
+ allocatorvmr=NULL;\r
+ }\r
+\r
+ if (dsrefclock) {\r
+ dsrefclock->Release();\r
+ dsrefclock=NULL;\r
+ }\r
+ if (dsmediafilter) {\r
+ dsmediafilter->Release();\r
+ dsmediafilter=NULL;\r
+ }\r
+\r
+\r
+ if (dsmediacontrol) {\r
+ dsmediacontrol->Stop();\r
+ dsmediacontrol->Release();\r
+ dsmediacontrol=NULL;\r
+ }\r
+ if (dsgraphbuilder){\r
+#ifdef DS_DEBUG\r
+ RemoveFromRot(graphidentifier);\r
+#endif\r
+ dsgraphbuilder->Release();\r
+ dsgraphbuilder=NULL;\r
+ sourcefilter=NULL; //The Graph Builder destroys our SourceFilter\r
+ }\r
+ ReleaseMutex(filtermutex);\r
+\r
+}\r
+\r
+\r
+UINT VideoWin::DeliverMediaSample(MediaPacket packet,\r
+ UCHAR* buffer,\r
+ UINT *samplepos)\r
+{\r
+ /*First Check, if we have an audio sample*/\r
+#ifdef DO_VIDEO\r
+ /*First Check, if we have an audio sample*/\r
+\r
+ IMediaSample* ms=NULL;\r
+ REFERENCE_TIME reftime1=0;\r
+ REFERENCE_TIME reftime2=0;\r
+\r
+ UINT headerstrip=0;\r
+ if (packet.disconti) {\r
+ firstsynched=false;\r
+ DeliverVideoMediaSample();\r
+\r
+ }\r
+\r
+\r
+ /*Inspect PES-Header */\r
+\r
+ if (*samplepos==0) {//stripheader\r
+ headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;\r
+ *samplepos+=headerstrip;\r
+ if ( packet.synched ) {\r
+ DeliverVideoMediaSample();//write out old data\r
+ /* if (packet.presentation_time<0) { //Preroll?\r
+ *samplepos=packet.length;//if we have not processed at least one\r
+ return packet.length;//synched packet ignore it!\r
+ }*/\r
+\r
+ reftime1=packet.presentation_time;\r
+ reftime2=reftime1+1;\r
+ firstsynched=true;\r
+ } else {\r
+ if (!firstsynched) {//\r
+ *samplepos=packet.length;//if we have not processed at least one\r
+ return packet.length;//synched packet ignore it!\r
+ }\r
+ }\r
+ }\r
+ BYTE *ms_buf;\r
+ UINT ms_length;\r
+ UINT ms_pos;\r
+ UINT haveToCopy;\r
+ if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample\r
+ samplepos=0;\r
+ MILLISLEEP(10);\r
+ return 0;\r
+ }\r
+ ms_pos=ms->GetActualDataLength();\r
+ ms_length=ms->GetSize();\r
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);\r
+ if ((ms_length-ms_pos)<1) {\r
+ DeliverVideoMediaSample(); //we are full!\r
+ if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample\r
+ samplepos=0;\r
+ MILLISLEEP(10);\r
+ return 0;\r
+ }\r
+ ms_pos=ms->GetActualDataLength();\r
+ ms_length=ms->GetSize();\r
+ haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);\r
+ }\r
+ ms->GetPointer(&ms_buf);\r
+\r
+\r
+ if (ms_pos==0) {//will only be changed on first packet\r
+ if (packet.disconti) {\r
+ ms->SetDiscontinuity(TRUE);\r
+ } else {\r
+ ms->SetDiscontinuity(FALSE);\r
+ }\r
+ if (packet.synched) {\r
+ ms->SetSyncPoint(TRUE);\r
+ ms->SetTime(&reftime1,&reftime2);\r
+ //ms->SetTime(NULL,NULL);\r
+ ms->SetMediaTime(NULL, NULL);\r
+ if (reftime1<0) ms->SetPreroll(TRUE);\r
+ else ms->SetPreroll(FALSE);\r
+ /*Timecode handling*/\r
+ lastreftimeRT=reftime1;\r
+ lastreftimeBYTE=packet.recording_byte_pos;\r
+\r
+ }else {\r
+ ms->SetSyncPoint(FALSE);\r
+ ms->SetTime(NULL,NULL);\r
+ ms->SetMediaTime(NULL, NULL);\r
+ ms->SetPreroll(FALSE);\r
+\r
+ // ms->SetSyncPoint(TRUE);\r
+ }\r
+ }\r
+\r
+\r
+ memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);\r
+ ms->SetActualDataLength(haveToCopy+ms_pos);\r
+\r
+ *samplepos+=haveToCopy;\r
+\r
+ return haveToCopy+headerstrip;\r
+\r
+#else\r
+\r
+ *samplepos+=packet.length;\r
+ MILLISLEEP(0); //yet not implemented//bad idea\r
+ return packet.length;\r
+#endif\r
+}\r
+\r
+int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)\r
+{\r
+ //WaitForSingleObject(filtermutex,INFINITE);\r
+ if (!sourcefilter){\r
+ // ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ if (cur_audio_media_sample) {\r
+ *ms=cur_audio_media_sample;//already open\r
+ return 1;\r
+ }\r
+ if (!sourcefilter->getCurrentAudioMediaSample(ms)) {\r
+ // ReleaseMutex(filtermutex);\r
+ }\r
+ if (*ms) (*ms)->SetActualDataLength(0);\r
+ cur_audio_media_sample=*ms;\r
+ //Don't release the mutex before deliver\r
+ return 1;\r
+}\r
+\r
+int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)\r
+{\r
+ //WaitForSingleObject(filtermutex,INFINITE);\r
+ if (!sourcefilter){\r
+ // ReleaseMutex(filtermutex);\r
+ return 0;\r
+ }\r
+ if (cur_video_media_sample) {\r
+ *ms=cur_video_media_sample;//already open\r
+ return 1;\r
+ }\r
+ if (!sourcefilter->getCurrentVideoMediaSample(ms)) {\r
+ // ReleaseMutex(filtermutex);\r
+ }\r
+ if (*ms) (*ms)->SetActualDataLength(0);\r
+\r
+ cur_video_media_sample=*ms;\r
+ //Don't release the mutex before deliver\r
+ return 1;\r
+}\r
+\r
+int VideoWin::DeliverAudioMediaSample(){\r
+ if (cur_audio_media_sample) {\r
+ sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);\r
+ cur_audio_media_sample=NULL;\r
+ }\r
+ //ReleaseMutex(filtermutex);\r
+ return 1;\r
+}\r
+\r
+int VideoWin::DeliverVideoMediaSample(){\r
+ if (cur_video_media_sample) {\r
+ sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);\r
+ cur_video_media_sample=NULL;\r
+ }\r
+ //ReleaseMutex(filtermutex);\r
+ return 1;\r
+}\r
+\r
+long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)\r
+{\r
+ *rsync=false;\r
+ if (offsetnotset) {\r
+ startoffset=curreftime;//offset is set for audio\r
+ offsetnotset=false;\r
+ offsetvideonotset=false;\r
+\r
+\r
+ } else {\r
+ if (offsetvideonotset) {\r
+ offsetvideonotset=false;\r
+ *rsync=true;\r
+ } else {\r
+ if ( (curreftime-lastrefvideotime)>10000000LL\r
+ || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync\r
+ startoffset+=curreftime-lastrefvideotime;\r
+ lastrefaudiotime+=curreftime-lastrefvideotime;\r
+ //*rsync=true;\r
+ offsetaudionotset=true;\r
+\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ lastrefvideotime=curreftime;\r
+ \r
+ return startoffset;\r
+\r
+}\r
+\r
+long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)\r
+{\r
+ *rsync=false;\r
+ if (offsetnotset) {\r
+ startoffset=curreftime;\r
+ offsetnotset=false;\r
+ offsetaudionotset=false;\r
+ }else {\r
+ if (offsetaudionotset) {\r
+ offsetaudionotset=false;\r
+ *rsync=true;\r
+ } else {\r
+ if ( (curreftime-lastrefaudiotime)>10000000LL\r
+ || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync\r
+ startoffset+=curreftime-lastrefaudiotime;\r
+ lastrefvideotime+=curreftime-lastrefaudiotime;\r
+ //*rsync=true;\r
+ offsetvideonotset=true;\r
+\r
+ }\r
+ }\r
+\r
+ }\r
+ lastrefaudiotime=curreftime;\r
+ return startoffset;\r
+\r
+}\r
+void VideoWin::ResetTimeOffsets() {\r
+ offsetnotset=true; //called from demuxer\r
+ offsetvideonotset=true;\r
+ offsetaudionotset=true;\r
+ startoffset=0;\r
+ lastrefaudiotime=0;\r
+ lastrefvideotime=0;\r
+ lastreftimeBYTE=0;\r
+ lastreftimeRT=0;\r
+\r
+\r
+}\r
+\r
+void VideoWin::SetAudioVolume(long volume)\r
+{\r
+ if (dsbasicaudio) dsbasicaudio->put_Volume(volume);\r
+}\r
+\r
+#ifdef DEV\r
+int VideoWin::test()\r
+{\r
+ return 0;\r
+}\r
+\r
+int VideoWin::test2()\r
+{\r
+ return 0;\r
+}\r
+#endif\r
\r
-/*
- 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 <stdio.h>
-#include <string.h>
-#include <winsock2.h>
-#include <dshow.h>
-#include <d3d9.h>
-#include <vmr9.h>
-
-#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
+/*\r
+ Copyright 2004-2005 Chris Tallon\r
+\r
+ This file is part of VOMP.\r
+\r
+ VOMP is free software; you can redistribute it and/or modify\r
+ it under the terms of the GNU General Public License as published by\r
+ the Free Software Foundation; either version 2 of the License, or\r
+ (at your option) any later version.\r
+\r
+ VOMP is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ GNU General Public License for more details.\r
+\r
+ You should have received a copy of the GNU General Public License\r
+ along with VOMP; if not, write to the Free Software\r
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
+*/\r
+\r
+#ifndef VIDEOWIN_H\r
+#define VIDEOWIN_H\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <winsock2.h>\r
+#include <dshow.h>\r
+#include <d3d9.h>\r
+#include <vmr9.h>\r
+\r
+#include "defines.h"\r
+#include "video.h"\r
+\r
+//#define DS_DEBUG\r
+\r
+class DsSourceFilter;\r
+class DsAllocator;\r
+\r
+class VideoWin : public Video\r
+{\r
+ public:\r
+ VideoWin();\r
+ ~VideoWin();\r
+\r
+ int init(UCHAR format);\r
+ int shutdown();\r
+\r
+ int setFormat(UCHAR format);\r
+ int setConnection(UCHAR connection);\r
+ int setAspectRatio(UCHAR aspectRatio); // This one does the pin 8 scart widescreen switching\r
+ UCHAR getAspectRatio(){return aspectRatio;};\r
+ UCHAR getMode(){return mode;};\r
+ UCHAR getPseudoTVsize() {return pseudotvsize;};\r
+ int setMode(UCHAR mode);\r
+ int setTVsize(UCHAR size); // Is the TV a widescreen?\r
+ int setDefaultAspect();\r
+ int setSource();\r
+ int setPosition(int x, int y);\r
+ int sync();\r
+ int play();\r
+ int stop();\r
+ int pause();\r
+ int unPause();\r
+ int fastForward();\r
+ int unFastForward();\r
+ int reset();\r
+ int blank();\r
+ int signalOn();\r
+ int signalOff();\r
+ int attachFrameBuffer(); // What does this do?\r
+ ULONG timecodeToFrameNumber(ULLONG timecode);\r
+ ULLONG frameNumberToTimecode(ULONG framenumber);\r
+ ULLONG getCurrentTimestamp();\r
+\r
+ //Writing Data to Videodevice\r
+ virtual UINT DeliverMediaSample(MediaPacket packet, UCHAR* buffer, UINT *samplepos);\r
+\r
+ int getCurrentAudioMediaSample(IMediaSample** ms);\r
+ int DeliverAudioMediaSample();\r
+\r
+ int getCurrentVideoMediaSample(IMediaSample** ms);\r
+ int DeliverVideoMediaSample();\r
+\r
+ virtual long long SetStartOffset(long long curreftime, bool *rsync);\r
+ long long SetStartAudioOffset(long long curreftime, bool *rsync);\r
+ virtual void ResetTimeOffsets();\r
+\r
+ void SetAudioState(bool state){audioon=state;};\r
+ void SetAudioVolume(long volume);\r
+\r
+ void turnVideoOn(){videoon=true;};\r
+ void turnVideoOff(){videoon=false;};\r
+\r
+ unsigned int getPosx() {return videoposx;};\r
+ unsigned int getPosy() {return videoposy;};\r
+ bool isVideoOn() {return videoon;};\r
+\r
+#ifdef DEV\r
+ int test();\r
+ int test2();\r
+#endif\r
+private:\r
+ IMediaControl* dsmediacontrol;\r
+\r
+ IGraphBuilder* dsgraphbuilder;\r
+ IMediaSample* cur_audio_media_sample;\r
+ IMediaSample* cur_video_media_sample;\r
+ IBaseFilter* dsvmrrenderer;\r
+ IVMRSurfaceAllocatorNotify9 *dsvmrsurfnotify;\r
+ IReferenceClock *dsrefclock;\r
+ IMediaFilter* dsmediafilter;\r
+ IBasicAudio* dsbasicaudio;\r
+ REFERENCE_TIME cr_time;\r
+\r
+ DsSourceFilter* sourcefilter;\r
+ DsAllocator* allocatorvmr;\r
+ HANDLE filtermutex;\r
+ void CleanupDS();\r
+ bool offsetnotset;\r
+ bool offsetvideonotset;\r
+ bool offsetaudionotset;\r
+ long long startoffset;\r
+ long long lastrefvideotime;\r
+ long long lastrefaudiotime;\r
+\r
+ bool firstsynched;\r
+ bool audioon;\r
+ bool videoon;\r
+ UCHAR pseudotvsize;\r
+ REFERENCE_TIME lastreftimeRT;\r
+ ULLONG lastreftimeBYTE;\r
+ unsigned int videoposx;\r
+ unsigned int videoposy;\r
+#ifdef DS_DEBUG\r
+ DWORD graphidentifier;\r
+#endif\r
+};\r
+\r
+#endif\r
\r