2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "dssourcefilter.h"
33 filtermutex=CreateMutex(NULL,FALSE,NULL);
35 offsetvideonotset=true;
36 offsetaudionotset=true;
41 cur_audio_media_sample=NULL;
42 cur_video_media_sample=NULL;
52 CloseHandle(filtermutex);
58 int VideoWin::init(UCHAR tformat)
60 if (initted) return 0;
63 if (!setFormat(tformat)){ shutdown(); return 0; }
67 int VideoWin::setTVsize(UCHAR ttvsize)
72 int VideoWin::setDefaultAspect()
74 return setAspectRatio(tvsize);
77 int VideoWin::shutdown()
79 if (!initted) return 0;
84 int VideoWin::setFormat(UCHAR tformat)
86 if (!initted) return 0;
87 if ((tformat != PAL) && (tformat != NTSC)) return 0;
103 int VideoWin::setConnection(UCHAR tconnection)
105 if (!initted) return 0;
106 if ((tconnection != COMPOSITERGB) && (tconnection != SVIDEO)) return 0;
107 connection = tconnection;
112 int VideoWin::setAspectRatio(UCHAR taspectRatio)
114 if (!initted) return 0;
115 if ((taspectRatio != ASPECT4X3) && (taspectRatio != ASPECT16X9)) return 0;
116 aspectRatio = taspectRatio;
121 int VideoWin::setMode(UCHAR tmode)
123 if (!initted) return 0;
125 if ((tmode == LETTERBOX) && (tvsize == ASPECT16X9)) return 0; // invalid mode
127 if ((tmode != NORMAL) && (tmode != LETTERBOX) && (tmode != UNKNOWN2) && (tmode != QUARTER) && (tmode != EIGHTH)
128 && (tmode != ZOOM) && (tmode != UNKNOWN6)) return 0;
134 int VideoWin::signalOff()
139 int VideoWin::signalOn()
144 int VideoWin::setSource()
146 if (!initted) return 0;
151 int VideoWin::setPosition(int x, int y)
153 if (!initted) return 0;
160 if (!initted) return 0;
165 #ifdef DS_DEBUG // This stuff would not included in vomp due to lincemse restrcitions
166 #include "dshelper.h"
173 if (!initted) return 0;
177 if (hres=CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
178 IID_IGraphBuilder,(void**)&dsgraphbuilder)!=S_OK) {
182 AddToRot(dsgraphbuilder,&graphidentifier);
184 //This is just a try to see if building the graph works
185 // dsgraphbuilder->RenderFile(L"D:\\Projekte\\VTP Client\\test.mpa" ,NULL);
186 //So this is the real code, this prevents the feeder from calling noexisting objects!
187 WaitForSingleObject(filtermutex,INFINITE);
189 offsetvideonotset=true;
190 offsetaudionotset=true;
192 sourcefilter=new DsSourceFilter(); //Creating our Source filter for pushing Data
194 if (hres=dsgraphbuilder->AddFilter(sourcefilter,L"Vomp Win Source Filter")!=S_OK) {
196 ReleaseMutex(filtermutex);
200 if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(0)/*audio*/)!=S_OK) {
202 ReleaseMutex(filtermutex);
208 if (hres=dsgraphbuilder->Render(sourcefilter->GetPin(1)/*video*/)!=S_OK) {
210 ReleaseMutex(filtermutex);
218 dsgraphbuilder->QueryInterface(IID_IMediaControl,(void **) &dsmediacontrol);
219 dsmediacontrol->Run();
220 ReleaseMutex(filtermutex);
226 if (!initted) return 0;
234 int VideoWin::reset()
236 if (!initted) return 0;
241 int VideoWin::pause()
243 if (!initted) return 0;
244 if (dsmediacontrol) dsmediacontrol->Pause();
248 int VideoWin::unPause() // FIXME get rid - same as play!!
249 {//No on windows this is not the same, I don't get rid of!
250 if (!initted) return 0;
251 if (dsmediacontrol) dsmediacontrol->Run();
255 int VideoWin::fastForward()
257 if (!initted) return 0;
261 int VideoWin::unFastForward()
263 if (!initted) return 0;
267 int VideoWin::attachFrameBuffer()
269 if (!initted) return 0;
273 int VideoWin::blank(void)
278 int VideoWin::getFD()
280 if (!initted) return 0;
285 ULLONG VideoWin::getCurrentTimestamp()
290 ULONG VideoWin::timecodeToFrameNumber(ULLONG timecode)
292 if (format == PAL) return (ULONG)(((double)timecode / (double)90000) * (double)25);
293 else return (ULONG)(((double)timecode / (double)90000) * (double)30);
296 void VideoWin::CleanupDS()
298 WaitForSingleObject(filtermutex,INFINITE);
299 if (cur_audio_media_sample) {
300 cur_audio_media_sample->Release();
301 cur_audio_media_sample=NULL;
303 if (cur_video_media_sample) {
304 cur_video_media_sample->Release();
305 cur_video_media_sample=NULL;
308 if (dsmediacontrol) {
309 dsmediacontrol->Stop();
310 dsmediacontrol->Release();
315 RemoveFromRot(graphidentifier);
317 dsgraphbuilder->Release();
319 sourcefilter=NULL; //The Graph Builder destroys our SourceFilter
321 ReleaseMutex(filtermutex);
326 UINT VideoWin::DeliverMediaSample(MediaPacket packet,
330 /*First Check, if we have an audio sample*/
332 /*First Check, if we have an audio sample*/
334 IMediaSample* ms=NULL;
335 REFERENCE_TIME reftime1=0;
336 REFERENCE_TIME reftime2=0;
339 if (packet.disconti) {
341 DeliverVideoMediaSample();
346 /*Inspect PES-Header */
348 if (*samplepos==0) {//stripheader
349 headerstrip=buffer[packet.pos_buffer+8]+9/*is this right*/;
350 *samplepos+=headerstrip;
351 if ( packet.synched ) {
352 DeliverVideoMediaSample();//write out old data
353 if (packet.presentation_time<0) { //Preroll?
354 *samplepos=packet.length;//if we have not processed at least one
355 return packet.length;//synched packet ignore it!
358 reftime1=packet.presentation_time;
362 if (!firstsynched) {//
363 *samplepos=packet.length;//if we have not processed at least one
364 return packet.length;//synched packet ignore it!
372 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
377 ms_pos=ms->GetActualDataLength();
378 ms_length=ms->GetSize();
379 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
380 if ((ms_length-ms_pos)<1) {
381 DeliverVideoMediaSample(); //we are full!
382 if (!getCurrentVideoMediaSample(&ms) || ms==NULL) {// get the current sample
387 ms_pos=ms->GetActualDataLength();
388 ms_length=ms->GetSize();
389 haveToCopy=min(ms_length-ms_pos,packet.length-*samplepos);
391 ms->GetPointer(&ms_buf);
394 if (ms_pos==0) {//will only be changed on first packet
395 if (packet.disconti) {
396 ms->SetDiscontinuity(TRUE);
398 ms->SetDiscontinuity(FALSE);
400 if (packet.synched) {
401 ms->SetSyncPoint(TRUE);
402 ms->SetTime(&reftime1,&reftime2);
403 //ms->SetTime(NULL,NULL);
404 ms->SetMediaTime(NULL, NULL);
406 ms->SetSyncPoint(FALSE);
407 ms->SetTime(NULL,NULL);
408 ms->SetMediaTime(NULL, NULL);
409 ms->SetSyncPoint(TRUE);
414 memcpy(ms_buf+ms_pos,buffer+packet.pos_buffer+*samplepos,haveToCopy);
415 ms->SetActualDataLength(haveToCopy+ms_pos);
417 *samplepos+=haveToCopy;
419 return haveToCopy+headerstrip;
423 *samplepos+=packet.length;
424 MILLISLEEP(0); //yet not implemented//bad idea
425 return packet.length;
429 int VideoWin::getCurrentAudioMediaSample(IMediaSample** ms)
431 //WaitForSingleObject(filtermutex,INFINITE);
433 // ReleaseMutex(filtermutex);
436 if (cur_audio_media_sample) {
437 *ms=cur_audio_media_sample;//already open
440 if (!sourcefilter->getCurrentAudioMediaSample(ms)) {
441 // ReleaseMutex(filtermutex);
443 if (*ms) (*ms)->SetActualDataLength(0);
444 cur_audio_media_sample=*ms;
445 //Don't release the mutex before deliver
449 int VideoWin::getCurrentVideoMediaSample(IMediaSample** ms)
451 //WaitForSingleObject(filtermutex,INFINITE);
453 // ReleaseMutex(filtermutex);
456 if (cur_video_media_sample) {
457 *ms=cur_video_media_sample;//already open
460 if (!sourcefilter->getCurrentVideoMediaSample(ms)) {
461 // ReleaseMutex(filtermutex);
463 if (*ms) (*ms)->SetActualDataLength(0);
465 cur_video_media_sample=*ms;
466 //Don't release the mutex before deliver
470 int VideoWin::DeliverAudioMediaSample(){
471 if (cur_audio_media_sample) {
472 sourcefilter->DeliverAudioMediaSample(cur_audio_media_sample);
473 cur_audio_media_sample=NULL;
475 //ReleaseMutex(filtermutex);
479 int VideoWin::DeliverVideoMediaSample(){
480 if (cur_video_media_sample) {
481 sourcefilter->DeliverVideoMediaSample(cur_video_media_sample);
482 cur_video_media_sample=NULL;
484 //ReleaseMutex(filtermutex);
488 long long VideoWin::SetStartOffset(long long curreftime, bool *rsync)
492 startoffset=curreftime;//offset is set for audio
494 offsetvideonotset=false;
496 if (offsetvideonotset) {
497 offsetvideonotset=false;
500 if ( (curreftime-lastrefvideotime)>10000000LL
501 || (curreftime-lastrefvideotime)<-10000000LL) {//if pts jumps to big resync
502 startoffset+=curreftime-lastrefvideotime;
503 //lastrefaudiotime+=curreftime-lastrefvideotime;
505 offsetaudionotset=true;
511 lastrefvideotime=curreftime;
516 long long VideoWin::SetStartAudioOffset(long long curreftime, bool *rsync)
520 startoffset=curreftime;
522 offsetaudionotset=false;
524 if (offsetaudionotset) {
525 offsetaudionotset=false;
528 if ( (curreftime-lastrefaudiotime)>10000000LL
529 || (curreftime-lastrefaudiotime)<-10000000LL) {//if pts jumps to big resync
530 startoffset+=curreftime-lastrefaudiotime;
531 lastrefvideotime+=curreftime-lastrefaudiotime;
533 offsetvideonotset=true;
539 lastrefaudiotime=curreftime;
552 int VideoWin::test2()