]> git.vomp.tv Git - vompclient.git/blob - dssourcepin.cc
Windows updates
[vompclient.git] / dssourcepin.cc
1 /*\r
2     Copyright 2004-2005 Chris Tallon\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 */\r
20 #include "dssourcepin.h"\r
21 #include "dssourcefilter.h"\r
22 #include <Dvdmedia.h>\r
23 #include <mmreg.h>\r
24 \r
25 \r
26 class DsSFEnumMediaTypes: public IEnumMediaTypes {\r
27 public:\r
28   DsSFEnumMediaTypes(DsSourcePin* papa,ULONG pos=0);\r
29   virtual ~DsSFEnumMediaTypes();\r
30   virtual HRESULT STDMETHODCALLTYPE Next(ULONG nummedia,  AM_MEDIA_TYPE **pins,ULONG *fetched);\r
31   virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);\r
32   virtual HRESULT STDMETHODCALLTYPE Reset();\r
33   virtual HRESULT STDMETHODCALLTYPE Clone(IEnumMediaTypes **enuma);\r
34   virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);\r
35   virtual ULONG STDMETHODCALLTYPE AddRef();\r
36     virtual ULONG STDMETHODCALLTYPE Release();\r
37 protected:\r
38   DsSourcePin* parent;\r
39   ULONG curpos;\r
40   volatile long refs;\r
41 };\r
42 \r
43 DsSFEnumMediaTypes::DsSFEnumMediaTypes(DsSourcePin* papa,ULONG pos){\r
44   parent=papa;\r
45   curpos=pos;\r
46   parent->AddRef();\r
47   refs=0;\r
48 }\r
49 \r
50 DsSFEnumMediaTypes::~DsSFEnumMediaTypes(){\r
51   parent->Release();\r
52 }\r
53 \r
54 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Next(ULONG numpin, AM_MEDIA_TYPE **pins,ULONG *fetched) {\r
55   int i;\r
56 \r
57   if (pins==NULL) return E_POINTER;\r
58   if (numpin!=1 && fetched==NULL) return E_INVALIDARG;\r
59   *fetched=0;\r
60 \r
61   for (i=0;(i<numpin);i++) {\r
62     pins[i]=(AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));\r
63         if (parent->GetMediaType(curpos+i,pins[i])!=S_OK) {\r
64                 CoTaskMemFree(pins[i]);\r
65                 pins[i]=NULL;\r
66                 return S_FALSE;\r
67         }    curpos++;\r
68     if (fetched!=NULL)  (*fetched)++;\r
69   }\r
70   return S_OK;\r
71 }\r
72 \r
73 HRESULT STDMETHODCALLTYPE   DsSFEnumMediaTypes::Skip(ULONG numpin){\r
74   curpos+=numpin;\r
75   if (curpos>1) return S_FALSE;\r
76   return S_OK;\r
77 }\r
78 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Reset(){\r
79   curpos=0;\r
80   return S_OK;\r
81 }\r
82 HRESULT STDMETHODCALLTYPE DsSFEnumMediaTypes::Clone(IEnumMediaTypes **enuma){\r
83   if (enuma==NULL) return E_POINTER;\r
84   *enuma=new DsSFEnumMediaTypes(parent,curpos);\r
85   (*enuma)->AddRef();\r
86   return S_OK;\r
87 }\r
88 \r
89 HRESULT STDMETHODCALLTYPE  DsSFEnumMediaTypes::QueryInterface(REFIID id,void ** object){\r
90   if (object==NULL) return E_POINTER;\r
91   if (id==IID_IUnknown ||id == IID_IEnumMediaTypes) {\r
92     *object=(IUnknown*)this;\r
93     ((IUnknown*)object)->AddRef();\r
94     return NOERROR;\r
95   } else {\r
96     *object=NULL;\r
97     return E_NOINTERFACE;\r
98   }\r
99 }\r
100 \r
101 \r
102 \r
103 ULONG STDMETHODCALLTYPE DsSFEnumMediaTypes::AddRef(){\r
104   InterlockedIncrement(&refs);\r
105   long tempref=refs;\r
106   if (tempref>1) return tempref;\r
107   else return 1;\r
108 }\r
109 \r
110 ULONG STDMETHODCALLTYPE DsSFEnumMediaTypes::Release(){\r
111   long tempref=InterlockedDecrement(&refs);\r
112 \r
113   if (tempref==0) {\r
114     refs++;\r
115     delete this;\r
116     return NULL;\r
117   } else {\r
118     if (tempref>1) return tempref;\r
119     else return 1;\r
120   }\r
121 }\r
122 \r
123 \r
124 void CopyMType(AM_MEDIA_TYPE* dest,const AM_MEDIA_TYPE*source) {\r
125   memcpy(dest,source,sizeof(AM_MEDIA_TYPE));\r
126   if (source->pbFormat!=NULL) {\r
127     dest->pbFormat=(BYTE*)CoTaskMemAlloc(dest->cbFormat);\r
128     memcpy(dest->pbFormat,source->pbFormat,dest->cbFormat);\r
129   }\r
130 }\r
131 void ReleaseMType(AM_MEDIA_TYPE* free) {\r
132   if (free->cbFormat!=NULL) CoTaskMemFree(free->pbFormat);\r
133   free->pbFormat=NULL;\r
134 }\r
135 \r
136 DsSourcePin::DsSourcePin(DsSourceFilter *pFilter,\r
137              HRESULT *phr,LPCWSTR pName,bool audio)\r
138 {\r
139   isaudiopin=audio;\r
140   m_pFilter=pFilter;\r
141   connected=NULL;\r
142   connectedinput=NULL;\r
143   allocator=NULL;\r
144 \r
145 \r
146 \r
147 }\r
148 \r
149 DsSourcePin::~DsSourcePin()\r
150 {\r
151 \r
152 \r
153 \r
154 }\r
155 \r
156 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInterface(REFIID id,void ** object){\r
157   if (object==NULL) return E_POINTER;\r
158   if (id==IID_IUnknown) {\r
159     *object=(IUnknown*)this;\r
160     ((IUnknown*)object)->AddRef();\r
161     return NOERROR;\r
162   } else if (id==IID_IPin) {\r
163     *object=(IPin*)this;\r
164     ((IPin*)object)->AddRef();\r
165     return NOERROR;\r
166   } else {\r
167     *object=NULL;\r
168     return E_NOINTERFACE;\r
169   }\r
170 }\r
171 \r
172 ULONG STDMETHODCALLTYPE DsSourcePin::AddRef(){\r
173   return m_pFilter->AddRef();\r
174 \r
175 }\r
176 ULONG STDMETHODCALLTYPE DsSourcePin::Release(){\r
177   return m_pFilter->Release();\r
178 }\r
179 \r
180 \r
181 /*IPin*/\r
182 HRESULT STDMETHODCALLTYPE DsSourcePin::Connect(IPin *pinempf,const AM_MEDIA_TYPE *mtype) {\r
183   if (pinempf==NULL) return E_POINTER;\r
184   EnterCriticalSection(&m_pFilter->filterlock);\r
185 \r
186   if (connected!=NULL) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_ALREADY_CONNECTED;}\r
187   if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}\r
188 \r
189 \r
190   bool gotmt=false;\r
191 \r
192   if (mtype!=NULL) {\r
193     if (CheckMediaType(mtype)==S_OK){\r
194       pinempf->AddRef();\r
195       if (pinempf->ReceiveConnection((IPin*)this,mtype)==S_OK) {\r
196         CopyMType(&medtype,mtype);\r
197         LeaveCriticalSection(&m_pFilter->filterlock);\r
198       } else {\r
199         LeaveCriticalSection(&m_pFilter->filterlock);\r
200   if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);\r
201         pinempf->Release();\r
202         return VFW_E_TYPE_NOT_ACCEPTED;\r
203       }\r
204 \r
205     } else {\r
206       LeaveCriticalSection(&m_pFilter->filterlock);\r
207  if (mtype->pbFormat!=NULL) CoTaskMemFree(mtype->pbFormat);\r
208       return VFW_E_TYPE_NOT_ACCEPTED;\r
209     }\r
210     CoTaskMemFree(mtype->pbFormat);\r
211   }else {\r
212     IEnumMediaTypes * emt;\r
213     EnumMediaTypes(&emt);\r
214     AM_MEDIA_TYPE  * emtype;\r
215     ULONG fetched=0;\r
216     pinempf->AddRef();\r
217     while (emt->Next(1,&emtype,&fetched)==S_OK) {\r
218       if (CheckMediaType(emtype)==S_OK){\r
219 /*      PIN_INFO pini;\r
220         pinempf->QueryPinInfo(&pini);\r
221         if (pini.pFilter!=NULL) {\r
222                 FILTER_INFO filti;\r
223                 pini.pFilter->QueryFilterInfo(&filti);\r
224 \r
225                 if (filti.pGraph!=NULL) filti.pGraph->Release();\r
226                 char buffer[MAX_FILTER_NAME*2];\r
227                 wcstombs(buffer,filti.achName,MAX_FILTER_NAME*2);\r
228                 MessageBox(0,buffer,"Filter",0);\r
229                 pini.pFilter->Release();\r
230         }*/\r
231 \r
232         if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {\r
233           connected=pinempf;\r
234           CopyMType(&medtype,emtype);\r
235  if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);\r
236                  \r
237                   CoTaskMemFree(emtype);\r
238           gotmt=true;\r
239           break;\r
240         }\r
241 \r
242       }\r
243  if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);\r
244           CoTaskMemFree(emtype);\r
245     }\r
246     emt->Release();\r
247     if (gotmt==false) {\r
248       pinempf->EnumMediaTypes(&emt);\r
249       while (emt->Next(1,&emtype,&fetched)==S_OK) {\r
250         if (CheckMediaType(emtype)==S_OK){\r
251           if (pinempf->ReceiveConnection((IPin*)this,emtype)==S_OK) {\r
252             connected=pinempf;\r
253             CopyMType(&medtype,emtype);\r
254             if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);\r
255                                                 CoTaskMemFree(emtype);\r
256             gotmt=true;\r
257             break;\r
258           }\r
259 \r
260         }\r
261         if (emtype->pbFormat!=NULL) CoTaskMemFree(emtype->pbFormat);\r
262                 CoTaskMemFree(emtype);\r
263       }\r
264       emt->Release();\r
265       if (gotmt==false) {\r
266         pinempf->Release();\r
267         LeaveCriticalSection(&m_pFilter->filterlock);\r
268         return VFW_E_NO_ACCEPTABLE_TYPES;\r
269       }\r
270     }\r
271   }\r
272 \r
273   if (pinempf->QueryInterface(IID_IMemInputPin,(void**)&connectedinput)!=S_OK) {\r
274     LeaveCriticalSection(&m_pFilter->filterlock);\r
275     connected->Release();\r
276     connected=NULL;\r
277   /*  connectedinput->Release();\r
278     connectedinput=NULL;*/\r
279     return VFW_E_NO_TRANSPORT;\r
280   }\r
281   ALLOCATOR_PROPERTIES eigenall;\r
282   ZeroMemory(&eigenall,sizeof(eigenall));\r
283   connectedinput->GetAllocatorRequirements(&eigenall);\r
284   if (eigenall.cbAlign==0) eigenall.cbAlign=1;\r
285   connectedinput->GetAllocator(&allocator);\r
286   if (DecideBufferSize(allocator,&eigenall)==S_OK) {\r
287     if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){\r
288       connected=pinempf;\r
289       LeaveCriticalSection(&m_pFilter->filterlock);\r
290       return S_OK;\r
291     }\r
292   }\r
293   if (allocator!=NULL) allocator->Release();\r
294   allocator=NULL;\r
295 \r
296   if (CoCreateInstance(CLSID_MemoryAllocator,0,CLSCTX_INPROC_SERVER,\r
297     IID_IMemAllocator,(void **)allocator)==S_OK) {\r
298       if (DecideBufferSize(allocator,&eigenall)==S_OK) {\r
299         if (connectedinput->NotifyAllocator(allocator,FALSE)==S_OK){\r
300           connected=pinempf;\r
301           LeaveCriticalSection(&m_pFilter->filterlock);\r
302         return S_OK;\r
303       }\r
304     }\r
305   }\r
306   if (allocator!=NULL) allocator->Release();\r
307   allocator=NULL;\r
308   connected->Release();\r
309   connected=NULL;\r
310   connectedinput->Release();\r
311   connectedinput=NULL;\r
312   LeaveCriticalSection(&m_pFilter->filterlock);\r
313   return VFW_E_NO_TRANSPORT;\r
314 \r
315 \r
316 \r
317 \r
318 }\r
319 HRESULT STDMETHODCALLTYPE DsSourcePin::ReceiveConnection(IPin *connect,\r
320                              const AM_MEDIA_TYPE *mtype){\r
321      return VFW_E_TYPE_NOT_ACCEPTED; //We have only output pins\r
322 }\r
323  HRESULT STDMETHODCALLTYPE DsSourcePin::Disconnect() {\r
324    EnterCriticalSection(&m_pFilter->filterlock);\r
325    if (connected!=NULL) {\r
326      if (m_pFilter->mystate!=State_Stopped) {LeaveCriticalSection(&m_pFilter->filterlock);return VFW_E_NOT_STOPPED;}\r
327      /*TODO: Decommit allocator*/\r
328      allocator->Decommit();\r
329      allocator->Release();\r
330      allocator=NULL;\r
331      ReleaseMType(&medtype);\r
332      connectedinput->Release();\r
333      connectedinput=NULL;\r
334      connected->Release();\r
335      connected=NULL;\r
336      LeaveCriticalSection(&m_pFilter->filterlock);\r
337      return S_OK;\r
338    }\r
339    LeaveCriticalSection(&m_pFilter->filterlock);\r
340    return S_FALSE;\r
341  }\r
342 \r
343  HRESULT STDMETHODCALLTYPE DsSourcePin::ConnectedTo(IPin **pin){\r
344    if (pin==NULL) return E_POINTER;\r
345    IPin* pinn=connected;\r
346    *pin=pinn;\r
347    if (pinn!=NULL) {\r
348      pinn->AddRef();\r
349      return S_OK;\r
350    } else {\r
351      return VFW_E_NOT_CONNECTED;\r
352    }\r
353  }\r
354  HRESULT STDMETHODCALLTYPE  DsSourcePin::ConnectionMediaType(AM_MEDIA_TYPE *mtype){\r
355    if (mtype==NULL) return E_POINTER;\r
356    if (connected!=NULL){\r
357     CopyMType(mtype,&medtype);\r
358     return S_OK;\r
359    } else {\r
360      ZeroMemory(mtype,sizeof(*mtype));\r
361      return VFW_E_NOT_CONNECTED;\r
362    }\r
363  }\r
364  HRESULT STDMETHODCALLTYPE DsSourcePin::QueryPinInfo(PIN_INFO *info){\r
365    if (info==NULL) return E_POINTER;\r
366    info->dir=PINDIR_OUTPUT;\r
367    info->pFilter=(IBaseFilter*)m_pFilter;\r
368    if (m_pFilter) m_pFilter->AddRef();\r
369    if (isaudiopin) wcscpy(info->achName,L"Audio");\r
370    else wcscpy(info->achName,L"Video");\r
371    return S_OK;\r
372  }\r
373 \r
374  HRESULT STDMETHODCALLTYPE  DsSourcePin::QueryDirection(PIN_DIRECTION *dir){\r
375    if (dir==NULL) return E_POINTER;\r
376    *dir=PINDIR_OUTPUT;\r
377    return S_OK;\r
378  }\r
379  HRESULT STDMETHODCALLTYPE DsSourcePin::QueryId(LPWSTR *id){\r
380    if (id==NULL) return E_POINTER;\r
381    *id=(LPWSTR)CoTaskMemAlloc(12);\r
382    if (*id==NULL) return E_OUTOFMEMORY;\r
383 \r
384 \r
385    if (isaudiopin) wcscpy(*id,L"Audio");\r
386     else  wcscpy(*id, L"Video");\r
387     return S_OK;\r
388  }\r
389  HRESULT STDMETHODCALLTYPE  DsSourcePin::QueryAccept(const AM_MEDIA_TYPE *mtype) {\r
390    if (mtype==NULL) return S_FALSE;\r
391    if (CheckMediaType(mtype)==S_OK) return S_OK;\r
392    else return S_FALSE;\r
393  }\r
394  HRESULT STDMETHODCALLTYPE DsSourcePin::EnumMediaTypes(IEnumMediaTypes **enuma){\r
395 if (enuma==NULL) return E_POINTER;\r
396   *enuma=new DsSFEnumMediaTypes( this);\r
397   (*enuma)->AddRef();\r
398   return S_OK;\r
399 }\r
400 \r
401 HRESULT STDMETHODCALLTYPE DsSourcePin::QueryInternalConnections(IPin **pin,ULONG *numpin){\r
402   return E_NOTIMPL;\r
403 }\r
404 HRESULT STDMETHODCALLTYPE DsSourcePin::EndOfStream(){\r
405   return E_UNEXPECTED; //we are a output pin!\r
406 }\r
407 \r
408 HRESULT STDMETHODCALLTYPE DsSourcePin::NewSegment(REFERENCE_TIME start,REFERENCE_TIME stop,double rate){\r
409   return E_UNEXPECTED;//we are a output pin!\r
410 }\r
411 \r
412 HRESULT DsSourcePin::getCurrentMediaSample(IMediaSample**ms){\r
413   if (allocator!=NULL) return allocator->GetBuffer(ms,NULL,NULL,0);\r
414   else return E_NOINTERFACE;\r
415 }\r
416 \r
417 HRESULT DsSourcePin::deliver(IMediaSample * ms){\r
418   //EnterCriticalSection(&m_pFilter->filterlock);\r
419   HRESULT hres;\r
420   if (connectedinput!=NULL)hres= connectedinput->Receive(ms);\r
421   else hres= VFW_E_NOT_CONNECTED;\r
422   //LeaveCriticalSection(&m_pFilter->filterlock);\r
423   return hres;\r
424 \r
425 }\r
426 \r
427 HRESULT DsSourcePin::GetMediaType(int iPosition, AM_MEDIA_TYPE *pmt)\r
428 {\r
429   HRESULT hr;\r
430 \r
431   if (isaudiopin){\r
432     if (iPosition==0) {\r
433       ZeroMemory(pmt,sizeof(*pmt));\r
434       pmt->lSampleSize = 1;\r
435       pmt->bFixedSizeSamples = TRUE;\r
436       pmt->majortype=MEDIATYPE_Audio;\r
437       MPEG1WAVEFORMAT wfe;\r
438       ZeroMemory(&wfe,sizeof(wfe));\r
439       wfe.wfx.cbSize=22;\r
440       wfe.wfx.nSamplesPerSec=48000;\r
441       wfe.wfx.nChannels=2;\r
442       wfe.wfx.nAvgBytesPerSec=32000;\r
443       wfe.wfx.nBlockAlign=768;\r
444       wfe.wfx.wFormatTag=WAVE_FORMAT_MPEG;\r
445           wfe.wfx.wBitsPerSample=0;\r
446       wfe.fwHeadLayer=2;\r
447       wfe.dwHeadBitrate=256000;\r
448       wfe.fwHeadMode=ACM_MPEG_STEREO;\r
449       wfe.fwHeadModeExt=1;\r
450       wfe.wHeadEmphasis=1;\r
451       wfe.fwHeadFlags=ACM_MPEG_ID_MPEG1 |ACM_MPEG_ORIGINALHOME | ACM_MPEG_PROTECTIONBIT;\r
452       pmt->subtype=MEDIASUBTYPE_MPEG2_AUDIO;\r
453       pmt->formattype=FORMAT_WaveFormatEx;\r
454       pmt->cbFormat=sizeof(wfe);\r
455       pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(wfe));\r
456       memcpy(pmt->pbFormat,&wfe,sizeof(wfe));\r
457       pmt->lSampleSize=0;\r
458       hr=S_OK;\r
459 \r
460 \r
461         } else  {\r
462       hr=VFW_S_NO_MORE_ITEMS ;\r
463     }\r
464   } else {\r
465     if (iPosition == 0) {\r
466       ZeroMemory(pmt,sizeof(*pmt));\r
467       pmt->lSampleSize = 1;\r
468       pmt->bFixedSizeSamples = TRUE;\r
469       pmt->majortype=MEDIATYPE_Video;\r
470       hr=S_OK;\r
471       pmt->subtype=MEDIASUBTYPE_MPEG2_VIDEO;\r
472             pmt->formattype=FORMAT_MPEG2Video;\r
473 \r
474             MPEG2VIDEOINFO hdr;\r
475             ZeroMemory(&hdr,sizeof(hdr));\r
476             hdr.dwProfile=AM_MPEG2Profile_Main;\r
477             hdr.dwLevel=AM_MPEG2Level_Main;\r
478             hdr.hdr.bmiHeader.biSize = sizeof(hdr.hdr.bmiHeader);\r
479             hdr.hdr.bmiHeader.biWidth = 720;\r
480             hdr.hdr.bmiHeader.biHeight = 568;\r
481       pmt->cbFormat=sizeof(hdr);\r
482       pmt->pbFormat=(BYTE*)CoTaskMemAlloc(sizeof(hdr));\r
483       memcpy(pmt->pbFormat,&hdr,sizeof(hdr));\r
484 \r
485     } else {\r
486       hr=VFW_S_NO_MORE_ITEMS;\r
487     }\r
488   }\r
489   return hr ;\r
490 }\r
491 \r
492 HRESULT DsSourcePin::Inactive() {\r
493   if (allocator!=NULL) return allocator->Decommit();\r
494   return VFW_E_NO_ALLOCATOR;\r
495 }\r
496 \r
497 HRESULT DsSourcePin::Active() {\r
498   if (allocator!=NULL) return allocator->Commit();\r
499   return VFW_E_NO_ALLOCATOR;\r
500 }\r
501 \r
502 \r
503 HRESULT DsSourcePin::Run(REFERENCE_TIME reftime){\r
504   return NOERROR;\r
505 }\r
506 \r
507 // No description\r
508 HRESULT DsSourcePin::CheckMediaType(const AM_MEDIA_TYPE *pmt)\r
509 {\r
510     HRESULT res;\r
511 \r
512     if (isaudiopin) {\r
513         bool subtype=false;\r
514 #if 0 /* For future demands ac3 */\r
515     subtype=pmt->subtype==(MEDIASUBTYPE_DOLBY_AC3);\r
516 #endif\r
517     subtype=(pmt->subtype==(MEDIASUBTYPE_MPEG2_AUDIO));\r
518         if (pmt->majortype==MEDIATYPE_Audio && subtype) {\r
519       res = S_OK ;\r
520         } else {\r
521             res = S_FALSE ;\r
522         }\r
523     } else {\r
524         if (pmt->majortype==MEDIATYPE_Video &&\r
525                   pmt-> subtype==MEDIASUBTYPE_MPEG2_VIDEO) {\r
526       res = S_OK ;\r
527         } else {\r
528             res = S_FALSE ;\r
529         }\r
530     }\r
531     return res;\r
532 }\r
533 \r
534 HRESULT DsSourcePin::DecideBufferSize(IMemAllocator *pa,ALLOCATOR_PROPERTIES *all_pp){\r
535   HRESULT hr;\r
536 \r
537     if (pa==NULL)return E_POINTER;\r
538     if (all_pp==NULL) return E_POINTER;\r
539   if (isaudiopin) {\r
540     if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)\r
541     {\r
542       //all_pp->cBuffers = 300;//old\r
543       all_pp->cBuffers = 10;\r
544       all_pp->cbBuffer = 64*1024;\r
545     }\r
546   } else {\r
547     if (all_pp->cBuffers*all_pp->cbBuffer < 300*64*1024)\r
548     {\r
549       //all_pp->cBuffers = 300;//old\r
550       all_pp->cBuffers = 30;\r
551       all_pp->cbBuffer = 64*1024;\r
552     }\r
553   }\r
554 \r
555     ALLOCATOR_PROPERTIES all_pp_cur;\r
556     hr =pa->SetProperties(all_pp,&all_pp_cur);\r
557     if (FAILED(hr))\r
558     {\r
559         return hr;\r
560     }\r
561     if (all_pp_cur.cbBuffer*all_pp_cur.cBuffers < all_pp->cBuffers*all_pp->cbBuffer)\r
562     {\r
563         return E_FAIL;\r
564     }\r
565 \r
566     return S_OK;\r
567 }\r
568 \r
569 \r