1 /* GStreamer
2  * Copyright <2006, 2007, 2008, 2009, 2010> Fluendo <support@fluendo.com>
3  * Copyright (C) 2007 Sebastien Moutte <sebastien@moutte.net>
4  *
5  * gstdshowfakesrc.cpp:
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #include "gstdshowfakesrc.h"
24 
25 GST_DEBUG_CATEGORY_EXTERN (dshowdec_debug);
26 #define GST_CAT_DEFAULT dshowdec_debug
27 
28 const GUID CLSID_DecodeFakeSrc =
29 { 0x039527db, 0x6b48, 0x45a7, { 0xab, 0xcf, 0x21, 0xab, 0xc5, 0x44, 0xbb, 0xb6} };
30 
31 static CCritSec g_pCriticSec;
32 
33 /* output pin*/
FakeOutputPin(CBaseFilter * pFilter,CCritSec * sec)34 FakeOutputPin::FakeOutputPin (CBaseFilter *pFilter, CCritSec *sec):
35   CBaseOutputPin("FakeOutputPin", pFilter, sec, &m_hres, L"output")
36 {
37 }
38 
~FakeOutputPin()39 FakeOutputPin::~FakeOutputPin()
40 {
41 }
42 
GetMediaType(int iPosition,CMediaType * pMediaType)43 HRESULT FakeOutputPin::GetMediaType(int iPosition,
44                                     CMediaType *pMediaType)
45 {
46   if(iPosition == 0) {
47     *pMediaType = m_MediaType;
48     return S_OK;
49   }
50 
51   return VFW_S_NO_MORE_ITEMS;
52 }
53 #if 0
54 #define GUID_FORMAT "0x%.8x 0x%.4x 0x%.4x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x"
55 #define GUID_ARGS(g) g.Data1, g.Data2, g.Data3, \
56   g.Data4[0], g.Data4[1], g.Data4[2], g.Data4[3], \
57   g.Data4[4], g.Data4[5], g.Data4[6], g.Data4[7]
58 
59 static void printMediaType (AM_MEDIA_TYPE *mt)
60 {
61   GST_DEBUG (":: majortype: "GUID_FORMAT, GUID_ARGS(mt->majortype));
62   GST_DEBUG (":: subtype: "GUID_FORMAT, GUID_ARGS(mt->subtype));
63 
64   GST_DEBUG (":: bFixedSizeSamples: %d", mt->bFixedSizeSamples);
65   GST_DEBUG (":: bTemporalCompression: %d", mt->bTemporalCompression);
66   GST_DEBUG (":: cbFormat: %d", mt->cbFormat);
67   GST_DEBUG (":: formattype: %x", mt->formattype);
68   GST_DEBUG (":: lSampleSize: %lu", mt->lSampleSize);
69   GST_DEBUG (":: pbFormat: %p", mt->pbFormat);
70 }
71 #endif
72 
CheckMediaType(const CMediaType * pmt)73 HRESULT FakeOutputPin::CheckMediaType(const CMediaType *pmt)
74 {
75   if (m_MediaType == *pmt) {
76     return S_OK;
77   }
78 
79   return S_FALSE;
80 }
81 
DecideBufferSize(IMemAllocator * pAlloc,ALLOCATOR_PROPERTIES * ppropInputRequest)82 HRESULT FakeOutputPin::DecideBufferSize (IMemAllocator *pAlloc,
83                                          ALLOCATOR_PROPERTIES *ppropInputRequest)
84 {
85   ALLOCATOR_PROPERTIES properties;
86   ppropInputRequest->cbBuffer = m_SampleSize;
87   ppropInputRequest->cBuffers = 1;
88   HRESULT hres = pAlloc->SetProperties(ppropInputRequest, &properties);
89   pAlloc->Commit();
90 
91   return S_OK;
92 }
93 
SetMediaType(AM_MEDIA_TYPE * pmt)94 STDMETHODIMP FakeOutputPin::SetMediaType (AM_MEDIA_TYPE *pmt)
95 {
96   m_MediaType.Set (*pmt);
97   m_SampleSize = m_MediaType.GetSampleSize();
98   return S_OK;
99 }
100 
PushBuffer(byte * buffer,__int64 start,__int64 stop,unsigned int size,bool discont)101 STDMETHODIMP FakeOutputPin::PushBuffer(byte *buffer,
102                                        __int64 start, __int64 stop,
103                                        unsigned int size, bool discont)
104 {
105   IMediaSample *pSample = NULL;
106 
107   if (start != -1) {
108     start /= 100;
109     stop /= 100;
110   }
111 
112   HRESULT hres = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
113   if (hres == S_OK && pSample)
114   {
115     BYTE *sample_buffer;
116     pSample->GetPointer(&sample_buffer);
117     if(sample_buffer)
118     {
119       memcpy (sample_buffer, buffer, size);
120       pSample->SetActualDataLength(size);
121     }
122     pSample->SetDiscontinuity(discont);
123 
124     pSample->SetSyncPoint(TRUE);
125     pSample->SetPreroll(FALSE);
126 
127     if (start != -1)
128       pSample->SetTime(&start, &stop);
129 
130     hres = Deliver(pSample);
131     pSample->Release();
132   }
133   else {
134     GST_WARNING ("unable to obtain a delivery buffer");
135   }
136 
137   return S_OK;
138 }
139 
Flush()140 STDMETHODIMP FakeOutputPin::Flush ()
141 {
142   DeliverBeginFlush();
143   DeliverEndFlush();
144   return S_OK;
145 }
146 
SetSampleSize(unsigned int size)147 STDMETHODIMP FakeOutputPin::SetSampleSize (unsigned int size)
148 {
149   m_SampleSize = size;
150   return S_OK;
151 }
152 
153 /* filter */
FakeSrc()154 FakeSrc::FakeSrc() :
155     CBaseFilter("DshowFakeSink", NULL, &g_pCriticSec, CLSID_DecodeFakeSrc)
156 {
157   m_pOutputPin = new FakeOutputPin((CSource *)this, m_pLock);
158 }
159 
~FakeSrc()160 FakeSrc::~FakeSrc()
161 {
162   if (m_pOutputPin)
163     delete m_pOutputPin;
164 }
165 
GetPinCount()166 int FakeSrc::GetPinCount()
167 {
168   return 1;
169 }
170 
GetPin(int n)171 CBasePin *FakeSrc::GetPin(int n)
172 {
173   return (CBasePin *)m_pOutputPin;
174 }
175 
GetOutputPin()176 FakeOutputPin *FakeSrc::GetOutputPin()
177 {
178   return m_pOutputPin;
179 }