CoderMixer2MT.cpp 5.9 KB

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