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