Home | History | Annotate | Download | only in Common
      1 // CoderMixer2MT.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "CoderMixer2MT.h"
      6 
      7 namespace NCoderMixer {
      8 
      9 CCoder2::CCoder2(UInt32 numInStreams, UInt32 numOutStreams):
     10     CCoderInfo2(numInStreams, numOutStreams)
     11 {
     12   InStreams.ClearAndReserve(NumInStreams);
     13   OutStreams.ClearAndReserve(NumOutStreams);
     14 }
     15 
     16 void CCoder2::Execute() { Code(NULL); }
     17 
     18 void 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 /*
     51 void 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 
     61 HRESULT 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 
     72 void CCoderMixer2MT::AddCoderCommon()
     73 {
     74   const CCoderStreamsInfo &c = _bindInfo.Coders[_coders.Size()];
     75   CCoder2 threadCoderInfo(c.NumInStreams, c.NumOutStreams);
     76   _coders.Add(threadCoderInfo);
     77 }
     78 
     79 void CCoderMixer2MT::AddCoder(ICompressCoder *coder)
     80 {
     81   AddCoderCommon();
     82   _coders.Back().Coder = coder;
     83 }
     84 
     85 void CCoderMixer2MT::AddCoder2(ICompressCoder2 *coder)
     86 {
     87   AddCoderCommon();
     88   _coders.Back().Coder2 = coder;
     89 }
     90 
     91 
     92 void CCoderMixer2MT::ReInit()
     93 {
     94   FOR_VECTOR (i, _streamBinders)
     95     _streamBinders[i].ReInit();
     96 }
     97 
     98 
     99 HRESULT 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 
    158 HRESULT 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 
    166 STDMETHODIMP 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