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);
142 void ReleaseMType(AM_MEDIA_TYPE* free) {
143 if (free->cbFormat!=NULL) CoTaskMemFree(free->pbFormat);
147 DsSourcePin::DsSourcePin(DsSourceFilter *pFilter,
148 HRESULT *phr,LPCWSTR pName,bool audio)
150 medtype.pbFormat=NULL;
162 pinmode=MPTYPE_MPEG_AUDIO;
163 //pinmode=MPTYPE_AC3;
168 pinmode=MPTYPE_VIDEO_MPEG2;
173 DsSourcePin::~DsSourcePin()
180 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInterface(REFIID id,void ** object){
181 if (object==NULL) return E_POINTER;
182 if (id==IID_IUnknown) {
183 *object=(IUnknown*)this;
184 ((IUnknown*)object)->AddRef();
186 } else if (id==IID_IPin) {
188 ((IPin*)object)->AddRef();
192 return E_NOINTERFACE;
196 ULONG STDMETHODCALLTYPE DsSourcePin::AddRef(){
197 return m_pFilter->AddRef();
200 ULONG STDMETHODCALLTYPE DsSourcePin::Release(){
201 return m_pFilter->Release();
206 HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE *mtype) {
207 if (pinempf==NULL) return E_POINTER;
208 EnterCriticalSection(&m_pFilter->filterlock);
210 if (connected!=NULL) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_ALREADY_CONNECTED;}
211 if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
216 if (CheckMediaType(mtype)==S_OK){
218 if (pinempf->ReceiveConnection((IPin*)this,mtype)==S_OK) {
219 CopyMType(&medtype,mtype);
220 LeaveCriticalSection(&m_pFilter->filterlock);
222 LeaveCriticalSection(&m_pFilter->filterlock);
223 if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);
225 return VFW_E_TYPE_NOT_ACCEPTED;
229 LeaveCriticalSection(&m_pFilter->filterlock);
230 if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);
231 return VFW_E_TYPE_NOT_ACCEPTED;
233 CoTaskMemFree(mtype->pbFormat);
235 IEnumMediaTypes * emt;
236 EnumMediaTypes(&emt);
237 AM_MEDIA_TYPE * emtype;
242 while (emt->Next(1,&emtype,&fetched)==S_OK) {
243 if (CheckMediaType(emtype)==S_OK){
245 pinempf->QueryPinInfo(&pini);
246 if (pini.pFilter!=NULL) {
248 pini.pFilter->QueryFilterInfo(&filti);
250 if (filti.pGraph!=NULL) filti.pGraph->Release();
251 char buffer[MAX_FILTER_NAME*2];
252 wcstombs(buffer,filti.achName,MAX_FILTER_NAME*2);
253 MessageBox(0,buffer,"Filter",0);
254 pini.pFilter->Release();
257 if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
259 CopyMType(&medtype,emtype);
260 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
262 CoTaskMemFree(emtype);
268 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
269 CoTaskMemFree(emtype);
273 pinempf->EnumMediaTypes(&emt);
274 while (emt->Next(1,&emtype,&fetched)==S_OK) {
275 if (CheckMediaType(emtype)==S_OK){
276 if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {
278 CopyMType(&medtype,emtype);
279 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
280 CoTaskMemFree(emtype);
286 if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);
287 CoTaskMemFree(emtype);
292 LeaveCriticalSection(&m_pFilter->filterlock);
293 return VFW_E_NO_ACCEPTABLE_TYPES;
298 if (pinempf->QueryInterface(IID_IMemInputPin,(void**)&connectedinput)!=S_OK) {
299 LeaveCriticalSection(&m_pFilter->filterlock);
300 connected->Release();
302 /* connectedinput->Release();
303 connectedinput=NULL;*/
304 return VFW_E_NO_TRANSPORT;
306 ALLOCATOR_PROPERTIES eigenall;
307 ZeroMemory(&eigenall,sizeof(eigenall));
308 connectedinput->GetAllocatorRequirements(&eigenall);
309 if (eigenall.cbAlign==0) eigenall.cbAlign=1;
310 connectedinput->GetAllocator(&allocator);
311 if (DecideBufferSize(allocator,&eigenall)==S_OK) {
312 if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){
314 LeaveCriticalSection(&m_pFilter->filterlock);
318 if (allocator!=NULL) allocator->Release();
321 if (CoCreateInstance(CLSID_MemoryAllocator,0,CLSCTX_INPROC_SERVER,
322 IID_IMemAllocator,(void **)allocator)==S_OK) {
323 if (DecideBufferSize(allocator,&eigenall)==S_OK) {
324 if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){
326 LeaveCriticalSection(&m_pFilter->filterlock);
331 if (allocator!=NULL) allocator->Release();
333 connected->Release();
335 connectedinput->Release();
337 LeaveCriticalSection(&m_pFilter->filterlock);
338 return VFW_E_NO_TRANSPORT;
344 HRESULT STDMETHODCALLTYPE DsSourcePin::ReceiveConnection(IPin *connect,
345 const AM_MEDIA_TYPE *mtype){
346 return VFW_E_TYPE_NOT_ACCEPTED; //We have only output pins
348 HRESULT STDMETHODCALLTYPE DsSourcePin::Disconnect() {
349 EnterCriticalSection(&m_pFilter->filterlock);
350 if (connected!=NULL) {
351 if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}
352 /*TODO: Decommit allocator*/
353 allocator->Decommit();
354 allocator->Release();
356 ReleaseMType(&medtype);
357 connectedinput->Release();
359 connected->Release();
361 LeaveCriticalSection(&m_pFilter->filterlock);
364 LeaveCriticalSection(&m_pFilter->filterlock);
368 HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectedTo(IPin **pin){
369 if (pin==NULL) return E_POINTER;
370 IPin* pinn=connected;
376 return VFW_E_NOT_CONNECTED;
379 HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectionMediaType(AM_MEDIA_TYPE *mtype){
380 if (mtype==NULL) return E_POINTER;
381 if (connected!=NULL){
382 CopyMType(mtype,&medtype);
385 ZeroMemory(mtype,sizeof(*mtype));
386 return VFW_E_NOT_CONNECTED;
389 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryPinInfo(PIN_INFO *info){
390 if (info==NULL) return E_POINTER;
391 info->dir=PINDIR_OUTPUT;
392 info->pFilter=(IBaseFilter*)m_pFilter;
393 if (m_pFilter) m_pFilter->AddRef();
394 if (isaudiopin) wcscpy(info->achName,L"Audio");
395 else wcscpy(info->achName,L"Video");
399 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryDirection(PIN_DIRECTION *dir){
400 if (dir==NULL) return E_POINTER;
404 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryId(LPWSTR *id){
405 if (id==NULL) return E_POINTER;
406 *id=(LPWSTR)CoTaskMemAlloc(12);
407 if (*id==NULL) return E_OUTOFMEMORY;
410 if (isaudiopin) wcscpy(*id,L"Audio");
411 else wcscpy(*id, L"Video");
414 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryAccept(const AM_MEDIA_TYPE *mtype) {
415 if (mtype==NULL) return S_FALSE;
416 if (CheckMediaType(mtype)==S_OK) return S_OK;
419 HRESULT STDMETHODCALLTYPE DsSourcePin::EnumMediaTypes(IEnumMediaTypes **enuma){
420 if (enuma==NULL) return E_POINTER;
421 *enuma=new DsSFEnumMediaTypes( this);
426 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInternalConnections(IPin **pin,ULONG *numpin){
429 HRESULT STDMETHODCALLTYPE DsSourcePin::EndOfStream(){
430 return E_UNEXPECTED; //we are a output pin!
433 HRESULT STDMETHODCALLTYPE DsSourcePin::NewSegment(REFERENCE_TIME start,REFERENCE_TIME stop,double rate){
434 return E_UNEXPECTED;//we are a output pin!
437 HRESULT DsSourcePin::getCurrentMediaSample(IMediaSample**ms){
438 if (allocator!=NULL) {
439 return allocator->GetBuffer(ms,NULL,NULL,0);
441 else return E_NOINTERFACE;
444 HRESULT DsSourcePin::deliver(IMediaSample * ms){
445 //EnterCriticalSection(&m_pFilter->filterlock);
449 if (connectedinput!=NULL)hres= connectedinput->Receive(ms);
450 else hres= VFW_E_NOT_CONNECTED;
451 //LeaveCriticalSection(&m_pFilter->filterlock);
456 void DsSourcePin::SetMsToMt(IMediaSample *ms) {
457 ms->SetMediaType(&medtype);
460 bool DsSourcePin::supportsAc3() {
463 return false; //Haha a video pin that supports ac3
467 return false; //Graph is not build, please wait
471 return false; //Graph is not build, please wait
473 IPinConnection *pinconn=NULL; //according to docs, this is the prefered method
474 if (connected->QueryInterface(IID_IPinConnection,(void**)&pinconn)==S_OK) {
476 GetMediaType(10,&test);
477 if (pinconn->DynamicQueryAccept(&test)==S_OK)
480 CoTaskMemFree(test.pbFormat);
484 CoTaskMemFree(test.pbFormat);
489 GetMediaTypeAc3(0,&test);
490 if (connected->QueryAccept(&test)==S_OK)
492 CoTaskMemFree(test.pbFormat);
495 CoTaskMemFree(test.pbFormat);
500 HRESULT DsSourcePin::GetMediaTypeMp3Audio(int iPosition, AM_MEDIA_TYPE *pmt)
506 ZeroMemory(pmt,sizeof(*pmt));
507 pmt->lSampleSize = 1;
508 pmt->bFixedSizeSamples = TRUE;
509 pmt->majortype=MEDIATYPE_Audio;
511 ZeroMemory(&wfe,sizeof(wfe));
513 wfe.wfx.nSamplesPerSec=48000;
515 wfe.wfx.nAvgBytesPerSec=32000;
516 wfe.wfx.nBlockAlign=768;
517 wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
518 wfe.wfx.wBitsPerSample=0;
520 wfe.dwHeadBitrate=256000;
521 wfe.fwHeadMode=ACM_MPEG_STEREO;
524 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
525 pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
526 pmt->formattype=FORMAT_WaveFormatEx;
527 pmt->cbFormat=sizeof(wfe);
528 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
529 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
533 /* case 0: //MPEG2_AUDIO
535 ZeroMemory(pmt,sizeof(*pmt));
536 pmt->lSampleSize = 1;
537 pmt->bFixedSizeSamples = TRUE;
538 pmt->majortype = MEDIATYPE_Audio;
540 ZeroMemory(&wfe,sizeof(wfe));
542 wfe.nSamplesPerSec = 48000;
544 wfe.nAvgBytesPerSec = 0;//32000;
545 wfe.nBlockAlign = 0;//768;
546 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
547 wfe.wBitsPerSample = 0;
548 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
549 pmt->formattype = FORMAT_WaveFormatEx;
550 pmt->cbFormat = sizeof(wfe);
551 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
552 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
557 ZeroMemory(pmt,sizeof(*pmt));
558 pmt->lSampleSize = 1;
559 pmt->bFixedSizeSamples = TRUE;
560 pmt->majortype = MEDIATYPE_Audio;
561 MPEGLAYER3WAVEFORMAT wfe;
562 ZeroMemory(&wfe,sizeof(wfe));
563 wfe.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
564 wfe.wfx.nSamplesPerSec =44100; //For the Fraunhofer decoder
565 wfe.wfx.nChannels = 2;
566 //wfe.wfx.nAvgBytesPerSec = 32000;
567 wfe.wfx.nAvgBytesPerSec = 0;//128*(1024/8);
568 wfe.wfx.nBlockAlign = 1;
569 wfe.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
570 wfe.wfx.wBitsPerSample = 0;
571 wfe.wID=MPEGLAYER3_ID_MPEG;
572 wfe.nCodecDelay=1393;
574 wfe.nFramesPerBlock=1;
575 pmt->subtype=MEDIATYPE_WaveFmt_Mpeg1Layer3;
578 pmt->formattype=FORMAT_WaveFormatEx;
579 pmt->cbFormat=sizeof(wfe);
580 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
581 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
585 case 1: //MPEG2_AUDIO, this more less not right but works on some filters
587 ZeroMemory(pmt,sizeof(*pmt));
588 pmt->lSampleSize = 1;
589 pmt->bFixedSizeSamples = TRUE;
590 pmt->majortype = MEDIATYPE_Audio;
592 ZeroMemory(&wfe,sizeof(wfe));
594 wfe.nSamplesPerSec = 48000;
596 wfe.nAvgBytesPerSec = 0;//32000;
597 wfe.nBlockAlign = 0;//768;
598 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
599 wfe.wBitsPerSample = 0;
600 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
601 pmt->formattype = FORMAT_WaveFormatEx;
602 pmt->cbFormat = sizeof(wfe);
603 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
604 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
609 hr=VFW_S_NO_MORE_ITEMS;
616 HRESULT DsSourcePin::GetMediaTypeMpegAudio(int iPosition, AM_MEDIA_TYPE *pmt)
622 ZeroMemory(pmt,sizeof(*pmt));
623 pmt->lSampleSize = 1;
624 pmt->bFixedSizeSamples = TRUE;
625 pmt->majortype=MEDIATYPE_Audio;
627 ZeroMemory(&wfe,sizeof(wfe));
629 wfe.wfx.nSamplesPerSec=48000;
631 wfe.wfx.nAvgBytesPerSec=32000;
632 wfe.wfx.nBlockAlign=768;
633 wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;
634 wfe.wfx.wBitsPerSample=0;
636 wfe.dwHeadBitrate=256000;
637 wfe.fwHeadMode=ACM_MPEG_STEREO;
640 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;
641 pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;
642 pmt->formattype=FORMAT_WaveFormatEx;
643 pmt->cbFormat=sizeof(wfe);
644 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
645 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
649 case 0: //MPEG2_AUDIO
651 ZeroMemory(pmt,sizeof(*pmt));
652 pmt->lSampleSize = 1;
653 pmt->bFixedSizeSamples = TRUE;
654 pmt->majortype = MEDIATYPE_Audio;
656 ZeroMemory(&wfe,sizeof(wfe));
658 wfe.nSamplesPerSec = 48000;
660 wfe.nAvgBytesPerSec = 0;//32000;
661 wfe.nBlockAlign = 0;//768;
662 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
663 wfe.wBitsPerSample = 0;
664 pmt->subtype = MEDIASUBTYPE_MPEG2_AUDIO;
665 pmt->formattype = FORMAT_WaveFormatEx;
666 pmt->cbFormat = sizeof(wfe);
667 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
668 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
673 ZeroMemory(pmt,sizeof(*pmt));
674 pmt->lSampleSize = 1;
675 pmt->bFixedSizeSamples = TRUE;
676 pmt->majortype = MEDIATYPE_Audio;
678 ZeroMemory(&wfe,sizeof(wfe));
680 wfe.wfx.nSamplesPerSec = 48000;
681 wfe.wfx.nChannels = 2;
682 //wfe.wfx.nAvgBytesPerSec = 32000;
683 wfe.wfx.nAvgBytesPerSec = 0;
684 //wfe.wfx.nBlockAlign = 768;
685 wfe.wfx.wFormatTag = WAVE_FORMAT_UNKNOWN;
686 wfe.wfx.wBitsPerSample = 0;
687 /* wfe.fwHeadLayer=2;
688 wfe.dwHeadBitrate=256000;
689 wfe.fwHeadMode=ACM_MPEG_STEREO;
692 wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;*/
693 pmt->subtype=MEDIASUBTYPE_MPEG1Payload;
694 pmt->formattype=FORMAT_WaveFormatEx;
695 pmt->cbFormat=sizeof(wfe);
696 pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));
697 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
702 hr=VFW_S_NO_MORE_ITEMS;
708 HRESULT DsSourcePin::GetMediaTypeAc3(int iPosition, AM_MEDIA_TYPE *pmt)
714 { //AC3 for future use
715 ZeroMemory(pmt,sizeof(*pmt));
716 pmt->lSampleSize = 1;
717 pmt->bFixedSizeSamples = TRUE;
718 pmt->majortype = MEDIATYPE_Audio;
720 ZeroMemory(&wfe,sizeof(wfe));
722 wfe.nSamplesPerSec = 48000;
724 wfe.nAvgBytesPerSec = 32000;
725 wfe.nBlockAlign = 768;
726 wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
727 wfe.wBitsPerSample = 0;
728 pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
729 // pmt->subtype = MEDIASUBTYPE_DOLBY_AC3_SPDIF;
730 pmt->formattype = FORMAT_WaveFormatEx;
731 pmt->cbFormat = sizeof(wfe);
732 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(wfe));
733 memcpy(pmt->pbFormat,&wfe,sizeof(wfe));
734 pmt->lSampleSize = 0;
738 hr=VFW_S_NO_MORE_ITEMS;
744 HRESULT DsSourcePin::GetMediaTypeMpegVideo(int iPosition, AM_MEDIA_TYPE *pmt)
749 ZeroMemory(pmt,sizeof(*pmt));
750 pmt->lSampleSize = 1;
751 pmt->bFixedSizeSamples = TRUE;
752 pmt->majortype = MEDIATYPE_Video;
754 pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
755 pmt->formattype = FORMAT_MPEG2Video;
757 ZeroMemory(&hdr,sizeof(hdr));
758 hdr.dwProfile = AM_MPEG2Profile_Main;
759 hdr.dwLevel = AM_MPEG2Level_Main;
760 hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);
761 hdr.hdr.bmiHeader.biWidth = v_width;
762 hdr.hdr.bmiHeader.biHeight = v_height;
764 hdr.hdr.dwPictAspectRatioX=1;//v_sar_width;
765 hdr.hdr.dwPictAspectRatioY=1;//v_sar_height;
767 pmt->cbFormat = sizeof(hdr);
768 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(hdr));
769 memcpy(pmt->pbFormat,&hdr,sizeof(hdr));
771 hr=VFW_S_NO_MORE_ITEMS;
777 HRESULT DsSourcePin::GetMediaTypeH264Video(int iPosition, AM_MEDIA_TYPE *pmt)
782 ZeroMemory(pmt,sizeof(*pmt));
783 pmt->lSampleSize = 1;
784 pmt->bFixedSizeSamples = TRUE;
785 pmt->majortype = MEDIATYPE_Video;
787 pmt->subtype =MEDIASUBTYPE_H264;// MAKEFOURCC('H','2','6','4');
788 pmt->formattype = FORMAT_VideoInfo2 ;
791 VIDEOINFOHEADER2 hdr;
792 ZeroMemory(&hdr,sizeof(hdr));
793 //hdr.dwProfile = AM_MPEG2Profile_Main;
794 //hdr.dwLevel = AM_MPEG2Level_Main;
795 hdr.bmiHeader.biSize = sizeof(hdr.bmiHeader);
796 hdr.bmiHeader.biWidth = v_width;//720;
797 hdr.bmiHeader.biHeight = v_height;//568;
798 hdr.bmiHeader.biCompression = MAKEFOURCC('H','2','6','4');
800 hdr.dwPictAspectRatioX=1;//v_sar_width;
801 hdr.dwPictAspectRatioY=1;//v_sar_height;
803 pmt->cbFormat = sizeof(hdr);
804 pmt->pbFormat = (BYTE*)CoTaskMemAlloc(sizeof(hdr));
805 memcpy(pmt->pbFormat,&hdr,sizeof(hdr));
807 hr=VFW_S_NO_MORE_ITEMS;
813 HRESULT DsSourcePin::GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt)
817 case MPTYPE_MPEG_AUDIO_LAYER3:
818 return GetMediaTypeMp3Audio(iPosition,pmt);
821 case MPTYPE_MPEG_AUDIO:
822 return GetMediaTypeMpegAudio(iPosition,pmt);
824 case MPTYPE_VIDEO_MPEG2:
825 return GetMediaTypeMpegVideo(iPosition,pmt);
827 case MPTYPE_VIDEO_H264:
828 return GetMediaTypeH264Video(iPosition,pmt);
830 case MPTYPE_AC3_PRE13:
832 return GetMediaTypeAc3(iPosition,pmt);
836 void DsSourcePin::SetPinMode(int mode, void* details) {
838 AM_MEDIA_TYPE amtype;
839 ReleaseMType(&medtype);
844 v_width=((mptype_video_detail*) details)->width;
845 v_height=((mptype_video_detail*) details)->height;
848 GetMediaType(0,&medtype);
851 HRESULT DsSourcePin::Inactive() {
852 if (allocator!=NULL) return allocator->Decommit();
853 return VFW_E_NO_ALLOCATOR;
856 HRESULT DsSourcePin::Active() {
857 if (allocator!=NULL) return allocator->Commit();
858 return VFW_E_NO_ALLOCATOR;
862 HRESULT DsSourcePin::Run(REFERENCE_TIME reftime){
867 HRESULT DsSourcePin::CheckMediaType(const AM_MEDIA_TYPE *pmt)
872 case MPTYPE_MPEG_AUDIO_LAYER3:
873 // subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
874 // subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
876 subtype=(pmt->subtype==MEDIATYPE_WaveFmt_Mpeg1Layer3);
877 subtype=subtype || (pmt->subtype==MEDIASUBTYPE_MPEG2_AUDIO);
878 if (pmt->majortype==MEDIATYPE_Audio && subtype)
888 case MPTYPE_MPEG_AUDIO:
889 subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));
890 subtype=(pmt->subtype==MEDIASUBTYPE_MPEG1Payload) || subtype;
891 if (pmt->majortype==MEDIATYPE_Audio && subtype)
900 case MPTYPE_VIDEO_MPEG2:
901 if (pmt->majortype==MEDIATYPE_Video &&
902 pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO)
911 case MPTYPE_VIDEO_H264:
912 if (pmt->majortype==MEDIATYPE_Video &&
913 pmt-> subtype==MEDIASUBTYPE_H264)
922 case MPTYPE_AC3_PRE13:
924 subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);
925 subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3_SPDIF) || subtype;
926 if (pmt->majortype==MEDIATYPE_Audio && subtype)
939 HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){
942 if (pa==NULL)return E_POINTER;
943 if (all_pp==NULL) return E_POINTER;
945 if (all_pp->cBuffers*all_pp->cbBuffer < 100*16*1024)
947 //all_pp->cBuffers = 300;//old
948 all_pp->cBuffers = 100;
949 all_pp->cbBuffer = 16*1024;
952 if (all_pp->cBuffers*all_pp->cbBuffer < 50*64*1024*5)
954 //all_pp->cBuffers = 300;//old
955 all_pp->cBuffers = 50;
956 all_pp->cbBuffer = 64*1024*5;
960 ALLOCATOR_PROPERTIES all_pp_cur;
961 hr =pa->SetProperties(all_pp,&all_pp_cur);
966 if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer)