5 #include "CoderMixer2MT.h"
7 namespace NCoderMixer {
9 CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
10 CCoderInfo2(numInStreams, numOutStreams)
12 InStreams.Reserve(NumInStreams);
13 InStreamPointers.Reserve(NumInStreams);
14 OutStreams.Reserve(NumOutStreams);
15 OutStreamPointers.Reserve(NumOutStreams);
18 void CCoder2::Execute() { Code(NULL); }
20 void CCoder2::Code(ICompressProgressInfo *progress)
22 InStreamPointers.Clear();
23 OutStreamPointers.Clear();
25 for (i = 0; i < NumInStreams; i++)
27 if (InSizePointers[i] != NULL)
28 InSizePointers[i] = &InSizes[i];
29 InStreamPointers.Add((ISequentialInStream *)InStreams[i]);
31 for (i = 0; i < NumOutStreams; i++)
33 if (OutSizePointers[i] != NULL)
34 OutSizePointers[i] = &OutSizes[i];
35 OutStreamPointers.Add((ISequentialOutStream *)OutStreams[i]);
38 Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0],
39 InSizePointers[0], OutSizePointers[0], progress);
41 Result = Coder2->Code(&InStreamPointers.Front(), &InSizePointers.Front(), NumInStreams,
42 &OutStreamPointers.Front(), &OutSizePointers.Front(), NumOutStreams, progress);
45 for (i = 0; i < InStreams.Size(); i++)
46 InStreams[i].Release();
47 for (i = 0; i < OutStreams.Size(); i++)
48 OutStreams[i].Release();
52 static void SetSizes(const UInt64 **srcSizes, CRecordVector<UInt64> &sizes,
53 CRecordVector<const UInt64 *> &sizePointers, UInt32 numItems)
57 for(UInt32 i = 0; i < numItems; i++)
59 if (srcSizes == 0 || srcSizes[i] == NULL)
62 sizePointers.Add(NULL);
66 sizes.Add(*srcSizes[i]);
67 sizePointers.Add(&sizes.Back());
73 void CCoder2::SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes)
75 SetSizes(inSizes, InSizes, InSizePointers, NumInStreams);
76 SetSizes(outSizes, OutSizes, OutSizePointers, NumOutStreams);
79 //////////////////////////////////////
82 HRESULT CCoderMixer2MT::SetBindInfo(const CBindInfo &bindInfo)
85 _streamBinders.Clear();
86 for(int i = 0; i < _bindInfo.BindPairs.Size(); i++)
88 _streamBinders.Add(CStreamBinder());
89 RINOK(_streamBinders.Back().CreateEvents());
94 void CCoderMixer2MT::AddCoderCommon()
96 const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
97 CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
98 _coders.Add(threadCoderInfo);
101 void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
104 _coders.Back().Coder = coder;
107 void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
110 _coders.Back().Coder2 = coder;
114 void CCoderMixer2MT::ReInit()
116 for(int i = 0; i < _streamBinders.Size(); i++)
117 _streamBinders[i].ReInit();
121 HRESULT CCoderMixer2MT::Init(ISequentialInStream **inStreams, ISequentialOutStream **outStreams)
124 if (_coders.Size() != _bindInfo.Coders.Size())
128 for(i = 0; i < _coders.Size(); i++)
130 CCoder2 &coderInfo = _coders[i];
131 const CCoderStreamsInfo &coderStreamsInfo = _bindInfo.Coders[i];
132 coderInfo.InStreams.Clear();
134 for(j = 0; j < coderStreamsInfo.NumInStreams; j++)
135 coderInfo.InStreams.Add(NULL);
136 coderInfo.OutStreams.Clear();
137 for(j = 0; j < coderStreamsInfo.NumOutStreams; j++)
138 coderInfo.OutStreams.Add(NULL);
141 for(i = 0; i < _bindInfo.BindPairs.Size(); i++)
143 const CBindPair &bindPair = _bindInfo.BindPairs[i];
144 UInt32 inCoderIndex, inCoderStreamIndex;
145 UInt32 outCoderIndex, outCoderStreamIndex;
146 _bindInfo.FindInStream(bindPair.InIndex, inCoderIndex, inCoderStreamIndex);
147 _bindInfo.FindOutStream(bindPair.OutIndex, outCoderIndex, outCoderStreamIndex);
149 _streamBinders[i].CreateStreams(
150 &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
151 &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
154 for(i = 0; i < _bindInfo.InStreams.Size(); i++)
156 UInt32 inCoderIndex, inCoderStreamIndex;
157 _bindInfo.FindInStream(_bindInfo.InStreams[i], inCoderIndex, inCoderStreamIndex);
158 _coders[inCoderIndex].InStreams[inCoderStreamIndex] = inStreams[i];
161 for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
163 UInt32 outCoderIndex, outCoderStreamIndex;
164 _bindInfo.FindOutStream(_bindInfo.OutStreams[i], outCoderIndex, outCoderStreamIndex);
165 _coders[outCoderIndex].OutStreams[outCoderStreamIndex] = outStreams[i];
170 HRESULT CCoderMixer2MT::ReturnIfError(HRESULT code)
172 for (int i = 0; i < _coders.Size(); i++)
173 if (_coders[i].Result == code)
178 STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
179 const UInt64 ** /* inSizes */,
181 ISequentialOutStream **outStreams,
182 const UInt64 ** /* outSizes */,
183 UInt32 numOutStreams,
184 ICompressProgressInfo *progress)
186 if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
187 numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
190 Init(inStreams, outStreams);
193 for (i = 0; i < _coders.Size(); i++)
194 if (i != _progressCoderIndex)
196 RINOK(_coders[i].Create());
199 for (i = 0; i < _coders.Size(); i++)
200 if (i != _progressCoderIndex)
203 _coders[_progressCoderIndex].Code(progress);
205 for (i = 0; i < _coders.Size(); i++)
206 if (i != _progressCoderIndex)
207 _coders[i].WaitFinish();
209 RINOK(ReturnIfError(E_ABORT));
210 RINOK(ReturnIfError(E_OUTOFMEMORY));
211 RINOK(ReturnIfError(S_FALSE));
213 for (i = 0; i < _coders.Size(); i++)
215 HRESULT result = _coders[i].Result;
216 if (result != S_OK && result != E_FAIL)
219 for (i = 0; i < _coders.Size(); i++)
221 HRESULT result = _coders[i].Result;