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
21 #include "dssourcefilter.h"
24 #include "draintarget.h"
25 #include "demuxeraudio.h"
27 EXTERN_C const GUID DECLSPEC_SELECTANY MEDIATYPE_WaveFmt_Mpeg1Layer3=
28 {WAVE_FORMAT_MPEGLAYER3,
29 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71};
31 #include "dssourcepin.h"
35 class DsSFEnumMediaTypes: public IEnumMediaTypes {
37 DsSFEnumMediaTypes(DsSourcePin* papa,ULONG pos=0);
38 virtual ~DsSFEnumMediaTypes();
39 virtual HRESULT STDMETHODCALLTYPE Next(ULONG nummedia, AM_MEDIA_TYPE **pins,ULONG *fetched);
40 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);
41 virtual HRESULT STDMETHODCALLTYPE Reset();
42 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes **enuma);
43 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
44 virtual ULONG STDMETHODCALLTYPE AddRef();
45 virtual ULONG STDMETHODCALLTYPE Release();
52 DsSFEnumMediaTypes::DsSFEnumMediaTypes(DsSourcePin* papa,ULONG pos){
59 DsSFEnumMediaTypes::~DsSFEnumMediaTypes(){
63 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Next(ULONG numpin, AM_MEDIA_TYPE **pins,ULONG *fetched) {
66 if (pins==NULL) return E_POINTER;
67 if (numpin!=1 && fetched==NULL) return E_INVALIDARG;
70 for (i=0;(i<numpin);i++) {
71 pins[i]=(AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
72 if (parent->GetMediaType(curpos+i,pins[i])!=S_OK) {
73 CoTaskMemFree(pins[i]);
77 if (fetched!=NULL) (*fetched)++;
82 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Skip(ULONG numpin){
84 if (curpos>1) return S_FALSE;
87 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Reset(){
91 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Clone(IEnumMediaTypes **enuma){
92 if (enuma==NULL) return E_POINTER;
93 *enuma=new DsSFEnumMediaTypes(parent,curpos);
98 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::QueryInterface(REFIID id,void ** object){
99 if (object==NULL) return E_POINTER;
100 if (id==IID_IUnknown ||id == IID_IEnumMediaTypes) {
101 *object=(IUnknown*)this;
102 ((IUnknown*)object)->AddRef();
106 return E_NOINTERFACE;
112 ULONG STDMETHODCALLTYPE DsSFEnumMediaTypes::AddRef(){
113 InterlockedIncrement(&refs);
115 if (tempref>1) return tempref;
119 ULONG STDMETHODCALLTYPE DsSFEnumMediaTypes::Release(){
120 long tempref=InterlockedDecrement(&refs);
127 if (tempref>1) return tempref;
133 void CopyMType(AM_MEDIA_TYPE* dest,const AM_MEDIA_TYPE*source) {
134 memcpy(dest,source,sizeof(AM_MEDIA_TYPE));
135 if (source->pbFormat!=NULL) {
136 dest->pbFormat=(BYTE*)CoTaskMemAlloc(dest->cbFormat);
137 memcpy(dest->pbFormat,source->pbFormat,dest->cbFormat);
140 void ReleaseMType(AM_MEDIA_TYPE* free) {
141 if (free->cbFormat!=NULL) CoTaskMemFree(free->pbFormat);
145 DsSourcePin::DsSourcePin(DsSourceFilter *pFilter,
146 HRESULT *phr,LPCWSTR pName,bool audio)
155 pinmode=MPTYPE_MPEG_AUDIO;
156 //pinmode=MPTYPE_AC3;
160 pinmode=MPTYPE_VIDEO;
165 DsSourcePin::~DsSourcePin()
172 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInterface(REFIID id,void ** object){
173 if (object==NULL) return E_POINTER;
174 if (id==IID_IUnknown) {
175 *object=(IUnknown*)this;
176 ((IUnknown*)object)->AddRef();
178 } else if (id==IID_IPin) {
180 ((IPin*)object)->AddRef();
184 return E_NOINTERFACE;
188 ULONG STDMETHODCALLTYPE DsSourcePin::AddRef(){
189 return m_pFilter->AddRef();
192 ULONG STDMETHODCALLTYPE DsSourcePin::Release(){
193 return m_pFilter->Release();
198 HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE *mtype) {
199 if (pinempf==NULL) return E_POINTER;
200 EnterCriticalSection(&m_pFilter->filterlock);
202 if (connected!=NULL) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_ALREADY_CONNECTED;}
203 if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
208 if (CheckMediaType(mtype)==S_OK){
210 if (pinempf->ReceiveConnection((IPin*)this,mtype)==S_OK) {
211 CopyMType(&medtype,mtype);
212 LeaveCriticalSection(&m_pFilter->filterlock);
214 LeaveCriticalSection(&m_pFilter->filterlock);
215 if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);
217 return VFW_E_TYPE_NOT_ACCEPTED;
221 LeaveCriticalSection(&m_pFilter->filterlock);
222 if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);
223 return VFW_E_TYPE_NOT_ACCEPTED;
225 CoTaskMemFree(mtype->pbFormat);
227 IEnumMediaTypes * emt;
228 EnumMediaTypes(&emt);
229 AM_MEDIA_TYPE * emtype;
234 while (emt->Next(1,&emtype,&fetched)==S_OK) {
235 if (CheckMediaType(emtype)==S_OK){
237 pinempf->QueryPinInfo(&pini);
238 if (pini.pFilter!=NULL) {
240 pini.pFilter->QueryFilterInfo(&filti);
242 if (filti.pGraph!=NULL) filti.pGraph->Release();
243 char buffer[MAX_FILTER_NAME*2];
244 wcstombs(buffer,filti.achName,MAX_FILTER_NAME*2);
245 MessageBox(0,buffer,"Filter",0);
246 pini.pFilter->Release();
249 if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
251 CopyMType(&medtype,emtype);
252 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
254 CoTaskMemFree(emtype);
260 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
261 CoTaskMemFree(emtype);
265 pinempf->EnumMediaTypes(&emt);
266 while (emt->Next(1,&emtype,&fetched)==S_OK) {
267 if (CheckMediaType(emtype)==S_OK){
268 if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
270 CopyMType(&medtype,emtype);
271 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
272 CoTaskMemFree(emtype);
278 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
279 CoTaskMemFree(emtype);
284 LeaveCriticalSection(&m_pFilter->filterlock);
285 return VFW_E_NO_ACCEPTABLE_TYPES;
290 if (pinempf->QueryInterface(IID_IMemInputPin,(void**)&connectedinput)!=S_OK) {
291 LeaveCriticalSection(&m_pFilter->filterlock);
292 connected->Release();
294 /* connectedinput->Release();
295 connectedinput=NULL;*/
296 return VFW_E_NO_TRANSPORT;
298 ALLOCATOR_PROPERTIES eigenall;
299 ZeroMemory(&eigenall,sizeof(eigenall));
300 connectedinput->GetAllocatorRequirements(&eigenall);
301 if (eigenall.cbAlign==0) eigenall.cbAlign=1;
302 connectedinput->GetAllocator(&allocator);
303 if (DecideBufferSize(allocator,&eigenall)==S_OK) {
304 if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){
306 LeaveCriticalSection(&m_pFilter->filterlock);
310 if (allocator!=NULL) allocator->Release();
313 if (CoCreateInstance(CLSID_MemoryAllocator,0,CLSCTX_INPROC_SERVER,
314 IID_IMemAllocator,(void **)allocator)==S_OK) {
315 if (DecideBufferSize(allocator,&eigenall)==S_OK) {
316 if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){
318 LeaveCriticalSection(&m_pFilter->filterlock);
323 if (allocator!=NULL) allocator->Release();
325 connected->Release();
327 connectedinput->Release();
329 LeaveCriticalSection(&m_pFilter->filterlock);
330 return VFW_E_NO_TRANSPORT;
336 HRESULT STDMETHODCALLTYPE DsSourcePin::ReceiveConnection(IPin *connect,
337 const AM_MEDIA_TYPE *mtype){
338 return VFW_E_TYPE_NOT_ACCEPTED; //We have only output pins
340 HRESULT STDMETHODCALLTYPE DsSourcePin::Disconnect() {
341 EnterCriticalSection(&m_pFilter->filterlock);
342 if (connected!=NULL) {
343 if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
344 /*TODO: Decommit allocator*/
345 allocator->Decommit();
346 allocator->Release();
348 ReleaseMType(&medtype);
349 connectedinput->Release();
351 connected->Release();
353 LeaveCriticalSection(&m_pFilter->filterlock);
356 LeaveCriticalSection(&m_pFilter->filterlock);
360 HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectedTo(IPin **pin){
361 if (pin==NULL) return E_POINTER;
362 IPin* pinn=connected;
368 return VFW_E_NOT_CONNECTED;
371 HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectionMediaType(AM_MEDIA_TYPE *mtype){
372 if (mtype==NULL) return E_POINTER;
373 if (connected!=NULL){
374 CopyMType(mtype,&medtype);
377 ZeroMemory(mtype,sizeof(*mtype));
378 return VFW_E_NOT_CONNECTED;
381 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryPinInfo(PIN_INFO *info){
382 if (info==NULL) return E_POINTER;
383 info->dir=PINDIR_OUTPUT;
384 info->pFilter=(IBaseFilter*)m_pFilter;
385 if (m_pFilter) m_pFilter->AddRef();
386 if (isaudiopin) wcscpy(info->achName,L"Audio");
387 else wcscpy(info->achName,L"Video");
391 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryDirection(PIN_DIRECTION *dir){
392 if (dir==NULL) return E_POINTER;
396 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryId(LPWSTR *id){
397 if (id==NULL) return E_POINTER;
398 *id=(LPWSTR)CoTaskMemAlloc(12);
399 if (*id==NULL) return E_OUTOFMEMORY;
402 if (isaudiopin) wcscpy(*id,L"Audio");
403 else wcscpy(*id, L"Video");
406 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryAccept(const AM_MEDIA_TYPE *mtype) {
407 if (mtype==NULL) return S_FALSE;
408 if (CheckMediaType(mtype)==S_OK) return S_OK;
411 HRESULT STDMETHODCALLTYPE DsSourcePin::EnumMediaTypes(IEnumMediaTypes **enuma){
412 if (enuma==NULL) return E_POINTER;
413 *enuma=new DsSFEnumMediaTypes( this);
418 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInternalConnections(IPin **pin,ULONG *numpin){
421 HRESULT STDMETHODCALLTYPE DsSourcePin::EndOfStream(){
422 return E_UNEXPECTED; //we are a output pin!
425 HRESULT STDMETHODCALLTYPE DsSourcePin::NewSegment(REFERENCE_TIME start,REFERENCE_TIME stop,double rate){
426 return E_UNEXPECTED;//we are a output pin!
429 HRESULT DsSourcePin::getCurrentMediaSample(IMediaSample**ms){
430 if (allocator!=NULL) return allocator->GetBuffer(ms,NULL,NULL,0);
431 else return E_NOINTERFACE;
434 HRESULT DsSourcePin::deliver(IMediaSample * ms){
435 //EnterCriticalSection(&m_pFilter->filterlock);
439 if (connectedinput!=NULL)hres= connectedinput->Receive(ms);
440 else hres= VFW_E_NOT_CONNECTED;
441 //LeaveCriticalSection(&m_pFilter->filterlock);
446 void DsSourcePin::SetMsToMt(IMediaSample *ms) {
447 ms->SetMediaType(&medtype);
450 bool DsSourcePin::supportsAc3() {
453 return false; //Haha a video pin that supports ac3
457 return false; //Graph is not build, please wait
461 return false; //Graph is not build, please wait
463 IPinConnection *pinconn=NULL; //according to docs, this is the prefered method
464 if (connected->QueryInterface(IID_IPinConnection,(void**)&pinconn)==S_OK) {
466 GetMediaType(10,&test);
467 if (pinconn->DynamicQueryAccept(&test)==S_OK)
470 CoTaskMemFree(test.pbFormat);
474 CoTaskMemFree(test.pbFormat);
479 GetMediaTypeAc3(0,&test);
480 if (connected->QueryAccept(&test)==S_OK)
482 CoTaskMemFree(test.pbFormat);
485 CoTaskMemFree(test.pbFormat);
490 HRESULT DsSourcePin::GetMediaTypeMp3Audio(int iPosition, AM_MEDIA_TYPE *pmt)
496 ZeroMemory(pmt,sizeof(*pmt));
497 pmt->lSampleSize = 1;
498 pmt->bFixedSizeSamples = TRUE;
499 pmt->majortype=MEDIATYPE_Audio;
501 ZeroMemory(&wfe,sizeof(wfe));
503 wfe.wfx.nSamplesPerSec=48000;
505 wfe.wfx.nAvgBytesPerSec=32000;
506 wfe.wfx.nBlockAlign=768;
507 wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
508 wfe.wfx.wBitsPerSample=0;
510 wfe.dwHeadBitrate=256000;
511 wfe.fwHeadMode=ACM_MPEG_STEREO;
514 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
515 pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
516 pmt->formattype=FORMAT_WaveFormatEx;
517 pmt->cbFormat=sizeof(wfe);
518 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
519 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
523 /* case 0: //MPEG2_AUDIO
525 ZeroMemory(pmt,sizeof(*pmt));
526 pmt->lSampleSize = 1;
527 pmt->bFixedSizeSamples = TRUE;
528 pmt->majortype = MEDIATYPE_Audio;
530 ZeroMemory(&wfe,sizeof(wfe));
532 wfe.nSamplesPerSec = 48000;
534 wfe.nAvgBytesPerSec = 0;//32000;
535 wfe.nBlockAlign = 0;//768;
536 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
537 wfe.wBitsPerSample = 0;
538 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
539 pmt->formattype = FORMAT_WaveFormatEx;
540 pmt->cbFormat = sizeof(wfe);
541 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
542 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
547 ZeroMemory(pmt,sizeof(*pmt));
548 pmt->lSampleSize = 1;
549 pmt->bFixedSizeSamples = TRUE;
550 pmt->majortype = MEDIATYPE_Audio;
551 MPEGLAYER3WAVEFORMAT wfe;
552 ZeroMemory(&wfe,sizeof(wfe));
553 wfe.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
554 wfe.wfx.nSamplesPerSec =44100; //For the Fraunhofer decoder
555 wfe.wfx.nChannels = 2;
556 //wfe.wfx.nAvgBytesPerSec = 32000;
557 wfe.wfx.nAvgBytesPerSec = 0;//128*(1024/8);
558 wfe.wfx.nBlockAlign = 1;
559 wfe.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
560 wfe.wfx.wBitsPerSample = 0;
561 wfe.wID=MPEGLAYER3_ID_MPEG;
562 wfe.nCodecDelay=1393;
564 wfe.nFramesPerBlock=1;
565 pmt->subtype=MEDIATYPE_WaveFmt_Mpeg1Layer3;
568 pmt->formattype=FORMAT_WaveFormatEx;
569 pmt->cbFormat=sizeof(wfe);
570 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
571 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
575 case 1: //MPEG2_AUDIO, this more less not right but works on some filters
577 ZeroMemory(pmt,sizeof(*pmt));
578 pmt->lSampleSize = 1;
579 pmt->bFixedSizeSamples = TRUE;
580 pmt->majortype = MEDIATYPE_Audio;
582 ZeroMemory(&wfe,sizeof(wfe));
584 wfe.nSamplesPerSec = 48000;
586 wfe.nAvgBytesPerSec = 0;//32000;
587 wfe.nBlockAlign = 0;//768;
588 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
589 wfe.wBitsPerSample = 0;
590 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
591 pmt->formattype = FORMAT_WaveFormatEx;
592 pmt->cbFormat = sizeof(wfe);
593 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
594 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
599 hr=VFW_S_NO_MORE_ITEMS;
606 HRESULT DsSourcePin::GetMediaTypeMpegAudio(int iPosition, AM_MEDIA_TYPE *pmt)
612 ZeroMemory(pmt,sizeof(*pmt));
613 pmt->lSampleSize = 1;
614 pmt->bFixedSizeSamples = TRUE;
615 pmt->majortype=MEDIATYPE_Audio;
617 ZeroMemory(&wfe,sizeof(wfe));
619 wfe.wfx.nSamplesPerSec=48000;
621 wfe.wfx.nAvgBytesPerSec=32000;
622 wfe.wfx.nBlockAlign=768;
623 wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
624 wfe.wfx.wBitsPerSample=0;
626 wfe.dwHeadBitrate=256000;
627 wfe.fwHeadMode=ACM_MPEG_STEREO;
630 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
631 pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
632 pmt->formattype=FORMAT_WaveFormatEx;
633 pmt->cbFormat=sizeof(wfe);
634 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
635 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
639 case 0: //MPEG2_AUDIO
641 ZeroMemory(pmt,sizeof(*pmt));
642 pmt->lSampleSize = 1;
643 pmt->bFixedSizeSamples = TRUE;
644 pmt->majortype = MEDIATYPE_Audio;
646 ZeroMemory(&wfe,sizeof(wfe));
648 wfe.nSamplesPerSec = 48000;
650 wfe.nAvgBytesPerSec = 0;//32000;
651 wfe.nBlockAlign = 0;//768;
652 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
653 wfe.wBitsPerSample = 0;
654 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
655 pmt->formattype = FORMAT_WaveFormatEx;
656 pmt->cbFormat = sizeof(wfe);
657 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
658 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
663 ZeroMemory(pmt,sizeof(*pmt));
664 pmt->lSampleSize = 1;
665 pmt->bFixedSizeSamples = TRUE;
666 pmt->majortype = MEDIATYPE_Audio;
668 ZeroMemory(&wfe,sizeof(wfe));
670 wfe.wfx.nSamplesPerSec = 48000;
671 wfe.wfx.nChannels = 2;
672 //wfe.wfx.nAvgBytesPerSec = 32000;
673 wfe.wfx.nAvgBytesPerSec = 0;
674 //wfe.wfx.nBlockAlign = 768;
675 wfe.wfx.wFormatTag = WAVE_FORMAT_UNKNOWN;
676 wfe.wfx.wBitsPerSample = 0;
677 /* wfe.fwHeadLayer=2;
678 wfe.dwHeadBitrate=256000;
679 wfe.fwHeadMode=ACM_MPEG_STEREO;
682 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;*/
683 pmt->subtype=MEDIASUBTYPE_MPEG1Payload;
684 pmt->formattype=FORMAT_WaveFormatEx;
685 pmt->cbFormat=sizeof(wfe);
686 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
687 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
692 hr=VFW_S_NO_MORE_ITEMS;
698 HRESULT DsSourcePin::GetMediaTypeAc3(int iPosition, AM_MEDIA_TYPE *pmt)
704 { //AC3 for future use
705 ZeroMemory(pmt,sizeof(*pmt));
706 pmt->lSampleSize = 1;
707 pmt->bFixedSizeSamples = TRUE;
708 pmt->majortype = MEDIATYPE_Audio;
710 ZeroMemory(&wfe,sizeof(wfe));
712 wfe.nSamplesPerSec = 48000;
714 wfe.nAvgBytesPerSec = 32000;
715 wfe.nBlockAlign = 768;
716 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
717 wfe.wBitsPerSample = 0;
718 pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
719 // pmt->subtype = MEDIASUBTYPE_DOLBY_AC3_SPDIF;
720 pmt->formattype = FORMAT_WaveFormatEx;
721 pmt->cbFormat = sizeof(wfe);
722 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
723 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
724 pmt->lSampleSize = 0;
728 hr=VFW_S_NO_MORE_ITEMS;
734 HRESULT DsSourcePin::GetMediaTypeMpegVideo(int iPosition, AM_MEDIA_TYPE *pmt)
739 ZeroMemory(pmt,sizeof(*pmt));
740 pmt->lSampleSize = 1;
741 pmt->bFixedSizeSamples = TRUE;
742 pmt->majortype = MEDIATYPE_Video;
744 pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
745 pmt->formattype = FORMAT_MPEG2Video;
747 ZeroMemory(&hdr,sizeof(hdr));
748 hdr.dwProfile = AM_MPEG2Profile_Main;
749 hdr.dwLevel = AM_MPEG2Level_Main;
750 hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);
751 hdr.hdr.bmiHeader.biWidth = 720;
752 hdr.hdr.bmiHeader.biHeight = 568;
753 pmt->cbFormat = sizeof(hdr);
754 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(hdr));
755 memcpy(pmt->pbFormat,&hdr,sizeof(hdr));
757 hr=VFW_S_NO_MORE_ITEMS;
763 HRESULT DsSourcePin::GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt)
767 case MPTYPE_MPEG_AUDIO_LAYER3:
768 return GetMediaTypeMp3Audio(iPosition,pmt);
771 case MPTYPE_MPEG_AUDIO:
772 return GetMediaTypeMpegAudio(iPosition,pmt);
775 return GetMediaTypeMpegVideo(iPosition,pmt);
777 case MPTYPE_AC3_PRE13:
779 return GetMediaTypeAc3(iPosition,pmt);
783 void DsSourcePin::SetPinMode(int mode) {
785 AM_MEDIA_TYPE amtype;
786 ReleaseMType(&medtype);
787 GetMediaType(0,&medtype);
790 HRESULT DsSourcePin::Inactive() {
791 if (allocator!=NULL) return allocator->Decommit();
792 return VFW_E_NO_ALLOCATOR;
795 HRESULT DsSourcePin::Active() {
796 if (allocator!=NULL) return allocator->Commit();
797 return VFW_E_NO_ALLOCATOR;
801 HRESULT DsSourcePin::Run(REFERENCE_TIME reftime){
806 HRESULT DsSourcePin::CheckMediaType(const AM_MEDIA_TYPE *pmt)
811 case MPTYPE_MPEG_AUDIO_LAYER3:
812 // subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
813 // subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
815 subtype=(pmt->subtype==MEDIATYPE_WaveFmt_Mpeg1Layer3);
816 subtype=subtype || (pmt->subtype==MEDIASUBTYPE_MPEG2_AUDIO);
817 if (pmt->majortype==MEDIATYPE_Audio && subtype)
827 case MPTYPE_MPEG_AUDIO:
828 subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
829 subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
830 if (pmt->majortype==MEDIATYPE_Audio && subtype)
840 if (pmt->majortype==MEDIATYPE_Video &&
841 pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO)
850 case MPTYPE_AC3_PRE13:
852 subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
853 subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3_SPDIF) || subtype;
854 if (pmt->majortype==MEDIATYPE_Audio && subtype)
867 HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){
870 if (pa==NULL)return E_POINTER;
871 if (all_pp==NULL) return E_POINTER;
873 if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
875 //all_pp->cBuffers = 300;//old
876 all_pp->cBuffers = 50;
877 all_pp->cbBuffer = 64*1024;
880 if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
882 //all_pp->cBuffers = 300;//old
883 all_pp->cBuffers = 300;
884 all_pp->cbBuffer = 64*1024;
888 ALLOCATOR_PROPERTIES all_pp_cur;
889 hr =pa->SetProperties(all_pp,&all_pp_cur);
894 if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer)