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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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)
148 medtype.pbFormat=NULL;
156 pinmode=MPTYPE_MPEG_AUDIO;
157 //pinmode=MPTYPE_AC3;
161 pinmode=MPTYPE_VIDEO;
166 DsSourcePin::~DsSourcePin()
173 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInterface(REFIID id,void ** object){
174 if (object==NULL) return E_POINTER;
175 if (id==IID_IUnknown) {
176 *object=(IUnknown*)this;
177 ((IUnknown*)object)->AddRef();
179 } else if (id==IID_IPin) {
181 ((IPin*)object)->AddRef();
185 return E_NOINTERFACE;
189 ULONG STDMETHODCALLTYPE DsSourcePin::AddRef(){
190 return m_pFilter->AddRef();
193 ULONG STDMETHODCALLTYPE DsSourcePin::Release(){
194 return m_pFilter->Release();
199 HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE *mtype) {
200 if (pinempf==NULL) return E_POINTER;
201 EnterCriticalSection(&m_pFilter->filterlock);
203 if (connected!=NULL) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_ALREADY_CONNECTED;}
204 if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
209 if (CheckMediaType(mtype)==S_OK){
211 if (pinempf->ReceiveConnection((IPin*)this,mtype)==S_OK) {
212 CopyMType(&medtype,mtype);
213 LeaveCriticalSection(&m_pFilter->filterlock);
215 LeaveCriticalSection(&m_pFilter->filterlock);
216 if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);
218 return VFW_E_TYPE_NOT_ACCEPTED;
222 LeaveCriticalSection(&m_pFilter->filterlock);
223 if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);
224 return VFW_E_TYPE_NOT_ACCEPTED;
226 CoTaskMemFree(mtype->pbFormat);
228 IEnumMediaTypes * emt;
229 EnumMediaTypes(&emt);
230 AM_MEDIA_TYPE * emtype;
235 while (emt->Next(1,&emtype,&fetched)==S_OK) {
236 if (CheckMediaType(emtype)==S_OK){
238 pinempf->QueryPinInfo(&pini);
239 if (pini.pFilter!=NULL) {
241 pini.pFilter->QueryFilterInfo(&filti);
243 if (filti.pGraph!=NULL) filti.pGraph->Release();
244 char buffer[MAX_FILTER_NAME*2];
245 wcstombs(buffer,filti.achName,MAX_FILTER_NAME*2);
246 MessageBox(0,buffer,"Filter",0);
247 pini.pFilter->Release();
250 if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
252 CopyMType(&medtype,emtype);
253 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
255 CoTaskMemFree(emtype);
261 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
262 CoTaskMemFree(emtype);
266 pinempf->EnumMediaTypes(&emt);
267 while (emt->Next(1,&emtype,&fetched)==S_OK) {
268 if (CheckMediaType(emtype)==S_OK){
269 if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
271 CopyMType(&medtype,emtype);
272 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
273 CoTaskMemFree(emtype);
279 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
280 CoTaskMemFree(emtype);
285 LeaveCriticalSection(&m_pFilter->filterlock);
286 return VFW_E_NO_ACCEPTABLE_TYPES;
291 if (pinempf->QueryInterface(IID_IMemInputPin,(void**)&connectedinput)!=S_OK) {
292 LeaveCriticalSection(&m_pFilter->filterlock);
293 connected->Release();
295 /* connectedinput->Release();
296 connectedinput=NULL;*/
297 return VFW_E_NO_TRANSPORT;
299 ALLOCATOR_PROPERTIES eigenall;
300 ZeroMemory(&eigenall,sizeof(eigenall));
301 connectedinput->GetAllocatorRequirements(&eigenall);
302 if (eigenall.cbAlign==0) eigenall.cbAlign=1;
303 connectedinput->GetAllocator(&allocator);
304 if (DecideBufferSize(allocator,&eigenall)==S_OK) {
305 if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){
307 LeaveCriticalSection(&m_pFilter->filterlock);
311 if (allocator!=NULL) allocator->Release();
314 if (CoCreateInstance(CLSID_MemoryAllocator,0,CLSCTX_INPROC_SERVER,
315 IID_IMemAllocator,(void **)allocator)==S_OK) {
316 if (DecideBufferSize(allocator,&eigenall)==S_OK) {
317 if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){
319 LeaveCriticalSection(&m_pFilter->filterlock);
324 if (allocator!=NULL) allocator->Release();
326 connected->Release();
328 connectedinput->Release();
330 LeaveCriticalSection(&m_pFilter->filterlock);
331 return VFW_E_NO_TRANSPORT;
337 HRESULT STDMETHODCALLTYPE DsSourcePin::ReceiveConnection(IPin *connect,
338 const AM_MEDIA_TYPE *mtype){
339 return VFW_E_TYPE_NOT_ACCEPTED; //We have only output pins
341 HRESULT STDMETHODCALLTYPE DsSourcePin::Disconnect() {
342 EnterCriticalSection(&m_pFilter->filterlock);
343 if (connected!=NULL) {
344 if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
345 /*TODO: Decommit allocator*/
346 allocator->Decommit();
347 allocator->Release();
349 ReleaseMType(&medtype);
350 connectedinput->Release();
352 connected->Release();
354 LeaveCriticalSection(&m_pFilter->filterlock);
357 LeaveCriticalSection(&m_pFilter->filterlock);
361 HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectedTo(IPin **pin){
362 if (pin==NULL) return E_POINTER;
363 IPin* pinn=connected;
369 return VFW_E_NOT_CONNECTED;
372 HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectionMediaType(AM_MEDIA_TYPE *mtype){
373 if (mtype==NULL) return E_POINTER;
374 if (connected!=NULL){
375 CopyMType(mtype,&medtype);
378 ZeroMemory(mtype,sizeof(*mtype));
379 return VFW_E_NOT_CONNECTED;
382 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryPinInfo(PIN_INFO *info){
383 if (info==NULL) return E_POINTER;
384 info->dir=PINDIR_OUTPUT;
385 info->pFilter=(IBaseFilter*)m_pFilter;
386 if (m_pFilter) m_pFilter->AddRef();
387 if (isaudiopin) wcscpy(info->achName,L"Audio");
388 else wcscpy(info->achName,L"Video");
392 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryDirection(PIN_DIRECTION *dir){
393 if (dir==NULL) return E_POINTER;
397 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryId(LPWSTR *id){
398 if (id==NULL) return E_POINTER;
399 *id=(LPWSTR)CoTaskMemAlloc(12);
400 if (*id==NULL) return E_OUTOFMEMORY;
403 if (isaudiopin) wcscpy(*id,L"Audio");
404 else wcscpy(*id, L"Video");
407 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryAccept(const AM_MEDIA_TYPE *mtype) {
408 if (mtype==NULL) return S_FALSE;
409 if (CheckMediaType(mtype)==S_OK) return S_OK;
412 HRESULT STDMETHODCALLTYPE DsSourcePin::EnumMediaTypes(IEnumMediaTypes **enuma){
413 if (enuma==NULL) return E_POINTER;
414 *enuma=new DsSFEnumMediaTypes( this);
419 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInternalConnections(IPin **pin,ULONG *numpin){
422 HRESULT STDMETHODCALLTYPE DsSourcePin::EndOfStream(){
423 return E_UNEXPECTED; //we are a output pin!
426 HRESULT STDMETHODCALLTYPE DsSourcePin::NewSegment(REFERENCE_TIME start,REFERENCE_TIME stop,double rate){
427 return E_UNEXPECTED;//we are a output pin!
430 HRESULT DsSourcePin::getCurrentMediaSample(IMediaSample**ms){
431 if (allocator!=NULL) return allocator->GetBuffer(ms,NULL,NULL,0);
432 else return E_NOINTERFACE;
435 HRESULT DsSourcePin::deliver(IMediaSample * ms){
436 //EnterCriticalSection(&m_pFilter->filterlock);
440 if (connectedinput!=NULL)hres= connectedinput->Receive(ms);
441 else hres= VFW_E_NOT_CONNECTED;
442 //LeaveCriticalSection(&m_pFilter->filterlock);
447 void DsSourcePin::SetMsToMt(IMediaSample *ms) {
448 ms->SetMediaType(&medtype);
451 bool DsSourcePin::supportsAc3() {
454 return false; //Haha a video pin that supports ac3
458 return false; //Graph is not build, please wait
462 return false; //Graph is not build, please wait
464 IPinConnection *pinconn=NULL; //according to docs, this is the prefered method
465 if (connected->QueryInterface(IID_IPinConnection,(void**)&pinconn)==S_OK) {
467 GetMediaType(10,&test);
468 if (pinconn->DynamicQueryAccept(&test)==S_OK)
471 CoTaskMemFree(test.pbFormat);
475 CoTaskMemFree(test.pbFormat);
480 GetMediaTypeAc3(0,&test);
481 if (connected->QueryAccept(&test)==S_OK)
483 CoTaskMemFree(test.pbFormat);
486 CoTaskMemFree(test.pbFormat);
491 HRESULT DsSourcePin::GetMediaTypeMp3Audio(int iPosition, AM_MEDIA_TYPE *pmt)
497 ZeroMemory(pmt,sizeof(*pmt));
498 pmt->lSampleSize = 1;
499 pmt->bFixedSizeSamples = TRUE;
500 pmt->majortype=MEDIATYPE_Audio;
502 ZeroMemory(&wfe,sizeof(wfe));
504 wfe.wfx.nSamplesPerSec=48000;
506 wfe.wfx.nAvgBytesPerSec=32000;
507 wfe.wfx.nBlockAlign=768;
508 wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
509 wfe.wfx.wBitsPerSample=0;
511 wfe.dwHeadBitrate=256000;
512 wfe.fwHeadMode=ACM_MPEG_STEREO;
515 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
516 pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
517 pmt->formattype=FORMAT_WaveFormatEx;
518 pmt->cbFormat=sizeof(wfe);
519 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
520 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
524 /* case 0: //MPEG2_AUDIO
526 ZeroMemory(pmt,sizeof(*pmt));
527 pmt->lSampleSize = 1;
528 pmt->bFixedSizeSamples = TRUE;
529 pmt->majortype = MEDIATYPE_Audio;
531 ZeroMemory(&wfe,sizeof(wfe));
533 wfe.nSamplesPerSec = 48000;
535 wfe.nAvgBytesPerSec = 0;//32000;
536 wfe.nBlockAlign = 0;//768;
537 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
538 wfe.wBitsPerSample = 0;
539 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
540 pmt->formattype = FORMAT_WaveFormatEx;
541 pmt->cbFormat = sizeof(wfe);
542 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
543 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
548 ZeroMemory(pmt,sizeof(*pmt));
549 pmt->lSampleSize = 1;
550 pmt->bFixedSizeSamples = TRUE;
551 pmt->majortype = MEDIATYPE_Audio;
552 MPEGLAYER3WAVEFORMAT wfe;
553 ZeroMemory(&wfe,sizeof(wfe));
554 wfe.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
555 wfe.wfx.nSamplesPerSec =44100; //For the Fraunhofer decoder
556 wfe.wfx.nChannels = 2;
557 //wfe.wfx.nAvgBytesPerSec = 32000;
558 wfe.wfx.nAvgBytesPerSec = 0;//128*(1024/8);
559 wfe.wfx.nBlockAlign = 1;
560 wfe.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
561 wfe.wfx.wBitsPerSample = 0;
562 wfe.wID=MPEGLAYER3_ID_MPEG;
563 wfe.nCodecDelay=1393;
565 wfe.nFramesPerBlock=1;
566 pmt->subtype=MEDIATYPE_WaveFmt_Mpeg1Layer3;
569 pmt->formattype=FORMAT_WaveFormatEx;
570 pmt->cbFormat=sizeof(wfe);
571 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
572 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
576 case 1: //MPEG2_AUDIO, this more less not right but works on some filters
578 ZeroMemory(pmt,sizeof(*pmt));
579 pmt->lSampleSize = 1;
580 pmt->bFixedSizeSamples = TRUE;
581 pmt->majortype = MEDIATYPE_Audio;
583 ZeroMemory(&wfe,sizeof(wfe));
585 wfe.nSamplesPerSec = 48000;
587 wfe.nAvgBytesPerSec = 0;//32000;
588 wfe.nBlockAlign = 0;//768;
589 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
590 wfe.wBitsPerSample = 0;
591 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
592 pmt->formattype = FORMAT_WaveFormatEx;
593 pmt->cbFormat = sizeof(wfe);
594 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
595 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
600 hr=VFW_S_NO_MORE_ITEMS;
607 HRESULT DsSourcePin::GetMediaTypeMpegAudio(int iPosition, AM_MEDIA_TYPE *pmt)
613 ZeroMemory(pmt,sizeof(*pmt));
614 pmt->lSampleSize = 1;
615 pmt->bFixedSizeSamples = TRUE;
616 pmt->majortype=MEDIATYPE_Audio;
618 ZeroMemory(&wfe,sizeof(wfe));
620 wfe.wfx.nSamplesPerSec=48000;
622 wfe.wfx.nAvgBytesPerSec=32000;
623 wfe.wfx.nBlockAlign=768;
624 wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
625 wfe.wfx.wBitsPerSample=0;
627 wfe.dwHeadBitrate=256000;
628 wfe.fwHeadMode=ACM_MPEG_STEREO;
631 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
632 pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
633 pmt->formattype=FORMAT_WaveFormatEx;
634 pmt->cbFormat=sizeof(wfe);
635 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
636 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
640 case 0: //MPEG2_AUDIO
642 ZeroMemory(pmt,sizeof(*pmt));
643 pmt->lSampleSize = 1;
644 pmt->bFixedSizeSamples = TRUE;
645 pmt->majortype = MEDIATYPE_Audio;
647 ZeroMemory(&wfe,sizeof(wfe));
649 wfe.nSamplesPerSec = 48000;
651 wfe.nAvgBytesPerSec = 0;//32000;
652 wfe.nBlockAlign = 0;//768;
653 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
654 wfe.wBitsPerSample = 0;
655 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
656 pmt->formattype = FORMAT_WaveFormatEx;
657 pmt->cbFormat = sizeof(wfe);
658 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
659 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
664 ZeroMemory(pmt,sizeof(*pmt));
665 pmt->lSampleSize = 1;
666 pmt->bFixedSizeSamples = TRUE;
667 pmt->majortype = MEDIATYPE_Audio;
669 ZeroMemory(&wfe,sizeof(wfe));
671 wfe.wfx.nSamplesPerSec = 48000;
672 wfe.wfx.nChannels = 2;
673 //wfe.wfx.nAvgBytesPerSec = 32000;
674 wfe.wfx.nAvgBytesPerSec = 0;
675 //wfe.wfx.nBlockAlign = 768;
676 wfe.wfx.wFormatTag = WAVE_FORMAT_UNKNOWN;
677 wfe.wfx.wBitsPerSample = 0;
678 /* wfe.fwHeadLayer=2;
679 wfe.dwHeadBitrate=256000;
680 wfe.fwHeadMode=ACM_MPEG_STEREO;
683 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;*/
684 pmt->subtype=MEDIASUBTYPE_MPEG1Payload;
685 pmt->formattype=FORMAT_WaveFormatEx;
686 pmt->cbFormat=sizeof(wfe);
687 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
688 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
693 hr=VFW_S_NO_MORE_ITEMS;
699 HRESULT DsSourcePin::GetMediaTypeAc3(int iPosition, AM_MEDIA_TYPE *pmt)
705 { //AC3 for future use
706 ZeroMemory(pmt,sizeof(*pmt));
707 pmt->lSampleSize = 1;
708 pmt->bFixedSizeSamples = TRUE;
709 pmt->majortype = MEDIATYPE_Audio;
711 ZeroMemory(&wfe,sizeof(wfe));
713 wfe.nSamplesPerSec = 48000;
715 wfe.nAvgBytesPerSec = 32000;
716 wfe.nBlockAlign = 768;
717 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
718 wfe.wBitsPerSample = 0;
719 pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
720 // pmt->subtype = MEDIASUBTYPE_DOLBY_AC3_SPDIF;
721 pmt->formattype = FORMAT_WaveFormatEx;
722 pmt->cbFormat = sizeof(wfe);
723 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
724 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
725 pmt->lSampleSize = 0;
729 hr=VFW_S_NO_MORE_ITEMS;
735 HRESULT DsSourcePin::GetMediaTypeMpegVideo(int iPosition, AM_MEDIA_TYPE *pmt)
740 ZeroMemory(pmt,sizeof(*pmt));
741 pmt->lSampleSize = 1;
742 pmt->bFixedSizeSamples = TRUE;
743 pmt->majortype = MEDIATYPE_Video;
745 pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
746 pmt->formattype = FORMAT_MPEG2Video;
748 ZeroMemory(&hdr,sizeof(hdr));
749 hdr.dwProfile = AM_MPEG2Profile_Main;
750 hdr.dwLevel = AM_MPEG2Level_Main;
751 hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);
752 hdr.hdr.bmiHeader.biWidth = 720;
753 hdr.hdr.bmiHeader.biHeight = 568;
755 hdr.hdr.dwPictAspectRatioX=1;
756 hdr.hdr.dwPictAspectRatioY=1;
758 pmt->cbFormat = sizeof(hdr);
759 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(hdr));
760 memcpy(pmt->pbFormat,&hdr,sizeof(hdr));
762 hr=VFW_S_NO_MORE_ITEMS;
768 HRESULT DsSourcePin::GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt)
772 case MPTYPE_MPEG_AUDIO_LAYER3:
773 return GetMediaTypeMp3Audio(iPosition,pmt);
776 case MPTYPE_MPEG_AUDIO:
777 return GetMediaTypeMpegAudio(iPosition,pmt);
780 return GetMediaTypeMpegVideo(iPosition,pmt);
782 case MPTYPE_AC3_PRE13:
784 return GetMediaTypeAc3(iPosition,pmt);
788 void DsSourcePin::SetPinMode(int mode) {
790 AM_MEDIA_TYPE amtype;
791 ReleaseMType(&medtype);
792 GetMediaType(0,&medtype);
795 HRESULT DsSourcePin::Inactive() {
796 if (allocator!=NULL) return allocator->Decommit();
797 return VFW_E_NO_ALLOCATOR;
800 HRESULT DsSourcePin::Active() {
801 if (allocator!=NULL) return allocator->Commit();
802 return VFW_E_NO_ALLOCATOR;
806 HRESULT DsSourcePin::Run(REFERENCE_TIME reftime){
811 HRESULT DsSourcePin::CheckMediaType(const AM_MEDIA_TYPE *pmt)
816 case MPTYPE_MPEG_AUDIO_LAYER3:
817 // subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
818 // subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
820 subtype=(pmt->subtype==MEDIATYPE_WaveFmt_Mpeg1Layer3);
821 subtype=subtype || (pmt->subtype==MEDIASUBTYPE_MPEG2_AUDIO);
822 if (pmt->majortype==MEDIATYPE_Audio && subtype)
832 case MPTYPE_MPEG_AUDIO:
833 subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
834 subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
835 if (pmt->majortype==MEDIATYPE_Audio && subtype)
845 if (pmt->majortype==MEDIATYPE_Video &&
846 pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO)
855 case MPTYPE_AC3_PRE13:
857 subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
858 subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3_SPDIF) || subtype;
859 if (pmt->majortype==MEDIATYPE_Audio && subtype)
872 HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){
875 if (pa==NULL)return E_POINTER;
876 if (all_pp==NULL) return E_POINTER;
878 if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
880 //all_pp->cBuffers = 300;//old
881 all_pp->cBuffers = 50;
882 all_pp->cbBuffer = 64*1024;
885 if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)
887 //all_pp->cBuffers = 300;//old
888 all_pp->cBuffers = 300;
889 all_pp->cbBuffer = 64*1024;
893 ALLOCATOR_PROPERTIES all_pp_cur;
894 hr =pa->SetProperties(all_pp,&all_pp_cur);
899 if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer)