168
|
1 #include <stdio.h>
|
|
2 #include "allocator.h"
|
|
3 #include <com.h>
|
|
4 #define E_NOTIMPL 0x80004001
|
713
|
5 using namespace std;
|
|
6
|
168
|
7 class AllocatorKeeper
|
|
8 {
|
|
9 public:
|
|
10 AllocatorKeeper()
|
|
11 {
|
|
12 RegisterComClass(&CLSID_MemoryAllocator, MemAllocator::CreateAllocator);
|
|
13 }
|
|
14 };
|
|
15 static AllocatorKeeper keeper;
|
|
16 GUID MemAllocator::interfaces[]=
|
|
17 {
|
|
18 IID_IUnknown,
|
|
19 IID_IMemAllocator,
|
|
20 };
|
|
21 IMPLEMENT_IUNKNOWN(MemAllocator)
|
|
22
|
|
23 MemAllocator::MemAllocator()
|
|
24 :refcount(1)
|
|
25 {
|
|
26 Debug printf("MemAllocator::MemAllocator() called\n");
|
|
27 vt=new IMemAllocator_vt;
|
|
28 vt->QueryInterface = QueryInterface;
|
|
29 vt->AddRef = AddRef;
|
|
30 vt->Release = Release;
|
|
31 vt->SetProperties = SetProperties;
|
|
32 vt->GetProperties = GetProperties;
|
|
33 vt->Commit = Commit;
|
|
34 vt->Decommit = Decommit;
|
|
35 vt->GetBuffer = GetBuffer;
|
|
36 vt->ReleaseBuffer = ReleaseBuffer;
|
|
37
|
|
38 props.cBuffers=1;
|
|
39 props.cbBuffer=65536;/* :/ */
|
|
40 props.cbAlign=props.cbPrefix=0;
|
713
|
41
|
|
42 new_pointer=0;
|
|
43 modified_sample=0;
|
168
|
44 }
|
|
45
|
|
46 long MemAllocator::CreateAllocator(GUID* clsid, GUID* iid, void** ppv)
|
|
47 {
|
|
48 if(!ppv)return -1;
|
|
49 *ppv=0;
|
|
50 if(memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID)))
|
|
51 return -1;
|
|
52
|
|
53 IMemAllocator* p=new MemAllocator;
|
|
54 int result=p->vt->QueryInterface((IUnknown*)p, iid, ppv);
|
|
55 p->vt->Release((IUnknown*)p);
|
|
56 return result;
|
|
57 }
|
|
58
|
|
59
|
|
60 /*
|
|
61 long cBuffers;
|
|
62 long cbBuffer;
|
|
63 long cbAlign;
|
|
64 long cbPrefix;
|
|
65 */
|
|
66 HRESULT STDCALL MemAllocator::SetProperties (
|
|
67 IMemAllocator * This,
|
|
68 /* [in] */ ALLOCATOR_PROPERTIES *pRequest,
|
|
69 /* [out] */ ALLOCATOR_PROPERTIES *pActual)
|
|
70 {
|
|
71 Debug printf("MemAllocator::SetProperties() called\n");
|
|
72 if(!pRequest)return 0x80004003;
|
|
73 if(!pActual)return 0x80004003;
|
|
74 if(pRequest->cBuffers<=0)return -1;
|
|
75 if(pRequest->cbBuffer<=0)return -1;
|
|
76 MemAllocator* me=(MemAllocator*)This;
|
|
77 if(me->used_list.size() || me->free_list.size())return -1;
|
|
78 me->props=*pRequest;
|
|
79 *pActual=*pRequest;
|
|
80 return 0;
|
|
81 }
|
|
82
|
|
83 HRESULT STDCALL MemAllocator::GetProperties (
|
|
84 IMemAllocator * This,
|
|
85 /* [out] */ ALLOCATOR_PROPERTIES *pProps)
|
|
86 {
|
|
87 Debug printf("MemAllocator::GetProperties() called\n");
|
|
88 if(!pProps)return -1;
|
|
89 if(((MemAllocator*)This)->props.cbBuffer<0)return -1;
|
|
90 *pProps=((MemAllocator*)This)->props;
|
|
91 return 0;
|
|
92 }
|
|
93
|
|
94 HRESULT STDCALL MemAllocator::Commit (
|
|
95 IMemAllocator * This)
|
|
96 {
|
|
97 Debug printf("MemAllocator::Commit() called\n");
|
|
98 MemAllocator* me=(MemAllocator*)This;
|
|
99 if(((MemAllocator*)This)->props.cbBuffer<0)return -1;
|
|
100 if(me->used_list.size() || me->free_list.size())return -1;
|
|
101 for(int i=0; i<me->props.cBuffers; i++)
|
|
102 me->free_list.push_back(new CMediaSample(me, me->props.cbBuffer));
|
|
103 return 0;
|
|
104 }
|
|
105
|
|
106 HRESULT STDCALL MemAllocator::Decommit (
|
|
107 IMemAllocator * This)
|
|
108 {
|
|
109 Debug printf("MemAllocator::Decommit() called\n");
|
|
110 MemAllocator* me=(MemAllocator*)This;
|
|
111 list<CMediaSample*>::iterator it;
|
|
112 for(it=me->free_list.begin(); it!=me->free_list.end(); it++)
|
|
113 delete *it;
|
|
114 for(it=me->used_list.begin(); it!=me->used_list.end(); it++)
|
|
115 delete *it;
|
|
116 me->free_list.clear();
|
|
117 me->used_list.clear();
|
|
118 return 0;
|
|
119 }
|
|
120
|
|
121 HRESULT STDCALL MemAllocator::GetBuffer (
|
|
122 IMemAllocator * This,
|
|
123 /* [out] */ IMediaSample **ppBuffer,
|
|
124 /* [in] */ REFERENCE_TIME *pStartTime,
|
|
125 /* [in] */ REFERENCE_TIME *pEndTime,
|
|
126 /* [in] */ DWORD dwFlags)
|
|
127 {
|
|
128 Debug printf("%x: MemAllocator::GetBuffer() called\n", This);
|
|
129 MemAllocator* me=(MemAllocator*)This;
|
|
130 if(me->free_list.size()==0)
|
|
131 {
|
|
132 Debug printf("No samples available\n");
|
|
133 return -1;//should block here if no samples are available
|
|
134 }
|
|
135 list<CMediaSample*>::iterator it=me->free_list.begin();
|
|
136 me->used_list.push_back(*it);
|
|
137 *ppBuffer=*it;
|
|
138 (*ppBuffer)->vt->AddRef((IUnknown*)*ppBuffer);
|
713
|
139 if(me->new_pointer)
|
|
140 {
|
|
141 if(me->modified_sample)
|
|
142 me->modified_sample->ResetPointer();
|
|
143 (*it)->SetPointer(me->new_pointer);
|
|
144 me->modified_sample=*it;
|
|
145 me->new_pointer=0;
|
|
146 }
|
168
|
147 me->free_list.remove(*it);
|
|
148 return 0;
|
|
149 }
|
|
150
|
|
151 HRESULT STDCALL MemAllocator::ReleaseBuffer (
|
|
152 IMemAllocator * This,
|
|
153 /* [in] */ IMediaSample *pBuffer)
|
|
154 {
|
|
155 Debug printf("%x: MemAllocator::ReleaseBuffer() called\n", This);
|
|
156 MemAllocator* me=(MemAllocator*)This;
|
|
157 list<CMediaSample*>::iterator it;
|
|
158 for(it=me->used_list.begin(); it!=me->used_list.end(); it++)
|
|
159 if(*it==pBuffer)
|
|
160 {
|
|
161 me->used_list.erase(it);
|
|
162 me->free_list.push_back((CMediaSample*)pBuffer);
|
|
163 return 0;
|
|
164 }
|
|
165 Debug printf("Releasing unknown buffer\n");
|
|
166 return -1;
|
|
167 }
|