rlm@1
|
1 // CoderMixer2MT.cpp
|
rlm@1
|
2
|
rlm@1
|
3 #include "StdAfx.h"
|
rlm@1
|
4
|
rlm@1
|
5 #include "CoderMixer2MT.h"
|
rlm@1
|
6
|
rlm@1
|
7 namespace NCoderMixer {
|
rlm@1
|
8
|
rlm@1
|
9 CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
|
rlm@1
|
10 CCoderInfo2(numInStreams, numOutStreams)
|
rlm@1
|
11 {
|
rlm@1
|
12 InStreams.Reserve(NumInStreams);
|
rlm@1
|
13 InStreamPointers.Reserve(NumInStreams);
|
rlm@1
|
14 OutStreams.Reserve(NumOutStreams);
|
rlm@1
|
15 OutStreamPointers.Reserve(NumOutStreams);
|
rlm@1
|
16 }
|
rlm@1
|
17
|
rlm@1
|
18 void CCoder2::Execute() { Code(NULL); }
|
rlm@1
|
19
|
rlm@1
|
20 void CCoder2::Code(ICompressProgressInfo *progress)
|
rlm@1
|
21 {
|
rlm@1
|
22 InStreamPointers.Clear();
|
rlm@1
|
23 OutStreamPointers.Clear();
|
rlm@1
|
24 UInt32 i;
|
rlm@1
|
25 for (i = 0; i < NumInStreams; i++)
|
rlm@1
|
26 {
|
rlm@1
|
27 if (InSizePointers[i] != NULL)
|
rlm@1
|
28 InSizePointers[i] = &InSizes[i];
|
rlm@1
|
29 InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
|
rlm@1
|
30 }
|
rlm@1
|
31 for (i = 0; i < NumOutStreams; i++)
|
rlm@1
|
32 {
|
rlm@1
|
33 if (OutSizePointers[i] != NULL)
|
rlm@1
|
34 OutSizePointers[i] = &OutSizes[i];
|
rlm@1
|
35 OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
|
rlm@1
|
36 }
|
rlm@1
|
37 if (Coder)
|
rlm@1
|
38 Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
|
rlm@1
|
39 InSizePointers[0], OutSizePointers[0], progress);
|
rlm@1
|
40 else
|
rlm@1
|
41 Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
|
rlm@1
|
42 &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
|
rlm@1
|
43 {
|
rlm@1
|
44 int i;
|
rlm@1
|
45 for (i = 0; i < InStreams.Size(); i++)
|
rlm@1
|
46 InStreams[i].Release();
|
rlm@1
|
47 for (i = 0; i < OutStreams.Size(); i++)
|
rlm@1
|
48 OutStreams[i].Release();
|
rlm@1
|
49 }
|
rlm@1
|
50 }
|
rlm@1
|
51
|
rlm@1
|
52 static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
|
rlm@1
|
53 CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
|
rlm@1
|
54 {
|
rlm@1
|
55 sizes.Clear();
|
rlm@1
|
56 sizePointers.Clear();
|
rlm@1
|
57 for(UInt32 i = 0; i < numItems; i++)
|
rlm@1
|
58 {
|
rlm@1
|
59 if (srcSizes == 0 || srcSizes[i] == NULL)
|
rlm@1
|
60 {
|
rlm@1
|
61 sizes.Add(0);
|
rlm@1
|
62 sizePointers.Add(NULL);
|
rlm@1
|
63 }
|
rlm@1
|
64 else
|
rlm@1
|
65 {
|
rlm@1
|
66 sizes.Add(*srcSizes[i]);
|
rlm@1
|
67 sizePointers.Add(&sizes.Back());
|
rlm@1
|
68 }
|
rlm@1
|
69 }
|
rlm@1
|
70 }
|
rlm@1
|
71
|
rlm@1
|
72
|
rlm@1
|
73 void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
|
rlm@1
|
74 {
|
rlm@1
|
75 SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
|
rlm@1
|
76 SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
|
rlm@1
|
77 }
|
rlm@1
|
78
|
rlm@1
|
79 //////////////////////////////////////
|
rlm@1
|
80 // CCoderMixer2MT
|
rlm@1
|
81
|
rlm@1
|
82 HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
|
rlm@1
|
83 {
|
rlm@1
|
84 _bindInfo = bindInfo;
|
rlm@1
|
85 _streamBinders.Clear();
|
rlm@1
|
86 for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
rlm@1
|
87 {
|
rlm@1
|
88 _streamBinders.Add(CStreamBinder());
|
rlm@1
|
89 RINOK(_streamBinders.Back().CreateEvents());
|
rlm@1
|
90 }
|
rlm@1
|
91 return S_OK;
|
rlm@1
|
92 }
|
rlm@1
|
93
|
rlm@1
|
94 void CCoderMixer2MT::AddCoderCommon()
|
rlm@1
|
95 {
|
rlm@1
|
96 const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
|
rlm@1
|
97 CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
|
rlm@1
|
98 _coders.Add(threadCoderInfo);
|
rlm@1
|
99 }
|
rlm@1
|
100
|
rlm@1
|
101 void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
|
rlm@1
|
102 {
|
rlm@1
|
103 AddCoderCommon();
|
rlm@1
|
104 _coders.Back().Coder = coder;
|
rlm@1
|
105 }
|
rlm@1
|
106
|
rlm@1
|
107 void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
|
rlm@1
|
108 {
|
rlm@1
|
109 AddCoderCommon();
|
rlm@1
|
110 _coders.Back().Coder2 = coder;
|
rlm@1
|
111 }
|
rlm@1
|
112
|
rlm@1
|
113
|
rlm@1
|
114 void CCoderMixer2MT::ReInit()
|
rlm@1
|
115 {
|
rlm@1
|
116 for(int i = 0; i < _streamBinders.Size(); i++)
|
rlm@1
|
117 _streamBinders[i].ReInit();
|
rlm@1
|
118 }
|
rlm@1
|
119
|
rlm@1
|
120
|
rlm@1
|
121 HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
|
rlm@1
|
122 {
|
rlm@1
|
123 /*
|
rlm@1
|
124 if (_coders.Size() != _bindInfo.Coders.Size())
|
rlm@1
|
125 throw 0;
|
rlm@1
|
126 */
|
rlm@1
|
127 int i;
|
rlm@1
|
128 for(i = 0; i < _coders.Size(); i++)
|
rlm@1
|
129 {
|
rlm@1
|
130 CCoder2 &coderInfo = _coders[i];
|
rlm@1
|
131 const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
|
rlm@1
|
132 coderInfo.InStreams.Clear();
|
rlm@1
|
133 UInt32 j;
|
rlm@1
|
134 for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
|
rlm@1
|
135 coderInfo.InStreams.Add(NULL);
|
rlm@1
|
136 coderInfo.OutStreams.Clear();
|
rlm@1
|
137 for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
|
rlm@1
|
138 coderInfo.OutStreams.Add(NULL);
|
rlm@1
|
139 }
|
rlm@1
|
140
|
rlm@1
|
141 for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
|
rlm@1
|
142 {
|
rlm@1
|
143 const CBindPair &bindPair = _bindInfo.BindPairs[i];
|
rlm@1
|
144 UInt32 inCoderIndex, inCoderStreamIndex;
|
rlm@1
|
145 UInt32 outCoderIndex, outCoderStreamIndex;
|
rlm@1
|
146 _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
|
rlm@1
|
147 _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
|
rlm@1
|
148
|
rlm@1
|
149 _streamBinders[i].CreateStreams(
|
rlm@1
|
150 &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
|
rlm@1
|
151 &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
|
rlm@1
|
152 }
|
rlm@1
|
153
|
rlm@1
|
154 for(i = 0; i < _bindInfo.InStreams.Size(); i++)
|
rlm@1
|
155 {
|
rlm@1
|
156 UInt32 inCoderIndex, inCoderStreamIndex;
|
rlm@1
|
157 _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
|
rlm@1
|
158 _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
|
rlm@1
|
159 }
|
rlm@1
|
160
|
rlm@1
|
161 for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
|
rlm@1
|
162 {
|
rlm@1
|
163 UInt32 outCoderIndex, outCoderStreamIndex;
|
rlm@1
|
164 _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
|
rlm@1
|
165 _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
|
rlm@1
|
166 }
|
rlm@1
|
167 return S_OK;
|
rlm@1
|
168 }
|
rlm@1
|
169
|
rlm@1
|
170 HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
|
rlm@1
|
171 {
|
rlm@1
|
172 for (int i = 0; i < _coders.Size(); i++)
|
rlm@1
|
173 if (_coders[i].Result == code)
|
rlm@1
|
174 return code;
|
rlm@1
|
175 return S_OK;
|
rlm@1
|
176 }
|
rlm@1
|
177
|
rlm@1
|
178 STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
|
rlm@1
|
179 const UInt64 ** /* inSizes */,
|
rlm@1
|
180 UInt32 numInStreams,
|
rlm@1
|
181 ISequentialOutStream **outStreams,
|
rlm@1
|
182 const UInt64 ** /* outSizes */,
|
rlm@1
|
183 UInt32 numOutStreams,
|
rlm@1
|
184 ICompressProgressInfo *progress)
|
rlm@1
|
185 {
|
rlm@1
|
186 if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
|
rlm@1
|
187 numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
|
rlm@1
|
188 return E_INVALIDARG;
|
rlm@1
|
189
|
rlm@1
|
190 Init(inStreams, outStreams);
|
rlm@1
|
191
|
rlm@1
|
192 int i;
|
rlm@1
|
193 for (i = 0; i < _coders.Size(); i++)
|
rlm@1
|
194 if (i != _progressCoderIndex)
|
rlm@1
|
195 {
|
rlm@1
|
196 RINOK(_coders[i].Create());
|
rlm@1
|
197 }
|
rlm@1
|
198
|
rlm@1
|
199 for (i = 0; i < _coders.Size(); i++)
|
rlm@1
|
200 if (i != _progressCoderIndex)
|
rlm@1
|
201 _coders[i].Start();
|
rlm@1
|
202
|
rlm@1
|
203 _coders[_progressCoderIndex].Code(progress);
|
rlm@1
|
204
|
rlm@1
|
205 for (i = 0; i < _coders.Size(); i++)
|
rlm@1
|
206 if (i != _progressCoderIndex)
|
rlm@1
|
207 _coders[i].WaitFinish();
|
rlm@1
|
208
|
rlm@1
|
209 RINOK(ReturnIfError(E_ABORT));
|
rlm@1
|
210 RINOK(ReturnIfError(E_OUTOFMEMORY));
|
rlm@1
|
211
|
rlm@1
|
212 for (i = 0; i < _coders.Size(); i++)
|
rlm@1
|
213 {
|
rlm@1
|
214 HRESULT result = _coders[i].Result;
|
rlm@1
|
215 if (result != S_OK && result != E_FAIL && result != S_FALSE)
|
rlm@1
|
216 return result;
|
rlm@1
|
217 }
|
rlm@1
|
218
|
rlm@1
|
219 RINOK(ReturnIfError(S_FALSE));
|
rlm@1
|
220
|
rlm@1
|
221 for (i = 0; i < _coders.Size(); i++)
|
rlm@1
|
222 {
|
rlm@1
|
223 HRESULT result = _coders[i].Result;
|
rlm@1
|
224 if (result != S_OK)
|
rlm@1
|
225 return result;
|
rlm@1
|
226 }
|
rlm@1
|
227 return S_OK;
|
rlm@1
|
228 }
|
rlm@1
|
229
|
rlm@1
|
230 }
|