blob: a59ce5fc09213b18afb3fec767d887e048a18892 [file] [log] [blame]
// CoderMixer2ST.cpp
#include "StdAfx.h"
#include "CoderMixer2ST.h"
namespace NCoderMixer2 {
CCoderMixer2ST::CCoderMixer2ST() {}
CCoderMixer2ST::~CCoderMixer2ST(){ }
HRESULT CCoderMixer2ST::SetBindInfo(const CBindInfo &bindInfo)
{
_bindInfo = bindInfo;
return S_OK;
}
void CCoderMixer2ST::AddCoderCommon(bool isMain)
{
const CCoderStreamsInfo &csi = _bindInfo.Coders[_coders.Size()];
_coders.Add(CSTCoderInfo(csi.NumInStreams, csi.NumOutStreams, isMain));
}
void CCoderMixer2ST::AddCoder(ICompressCoder *coder, bool isMain)
{
AddCoderCommon(isMain);
_coders.Back().Coder = coder;
}
void CCoderMixer2ST::AddCoder2(ICompressCoder2 *coder, bool isMain)
{
AddCoderCommon(isMain);
_coders.Back().Coder2 = coder;
}
void CCoderMixer2ST::ReInit() { }
HRESULT CCoderMixer2ST::GetInStream(
ISequentialInStream **inStreams, const UInt64 **inSizes,
UInt32 streamIndex, ISequentialInStream **inStreamRes)
{
CMyComPtr<ISequentialInStream> seqInStream;
int i;
for(i = 0; i < _bindInfo.InStreams.Size(); i++)
if (_bindInfo.InStreams[i] == streamIndex)
{
seqInStream = inStreams[i];
*inStreamRes = seqInStream.Detach();
return S_OK;
}
int binderIndex = _bindInfo.FindBinderForInStream(streamIndex);
if (binderIndex < 0)
return E_INVALIDARG;
UInt32 coderIndex, coderStreamIndex;
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
coderIndex, coderStreamIndex);
CCoderInfo &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
if (!seqInStream)
return E_NOTIMPL;
UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex);
CMyComPtr<ICompressSetInStream> setInStream;
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream);
if (!setInStream)
return E_NOTIMPL;
if (coder.NumInStreams > 1)
return E_NOTIMPL;
for (i = 0; i < (int)coder.NumInStreams; i++)
{
CMyComPtr<ISequentialInStream> seqInStream2;
RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2));
RINOK(setInStream->SetInStream(seqInStream2));
}
*inStreamRes = seqInStream.Detach();
return S_OK;
}
HRESULT CCoderMixer2ST::GetOutStream(
ISequentialOutStream **outStreams, const UInt64 **outSizes,
UInt32 streamIndex, ISequentialOutStream **outStreamRes)
{
CMyComPtr<ISequentialOutStream> seqOutStream;
int i;
for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
if (_bindInfo.OutStreams[i] == streamIndex)
{
seqOutStream = outStreams[i];
*outStreamRes = seqOutStream.Detach();
return S_OK;
}
int binderIndex = _bindInfo.FindBinderForOutStream(streamIndex);
if (binderIndex < 0)
return E_INVALIDARG;
UInt32 coderIndex, coderStreamIndex;
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
coderIndex, coderStreamIndex);
CCoderInfo &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
if (!seqOutStream)
return E_NOTIMPL;
UInt32 startIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);
CMyComPtr<ICompressSetOutStream> setOutStream;
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream);
if (!setOutStream)
return E_NOTIMPL;
if (coder.NumOutStreams > 1)
return E_NOTIMPL;
for (i = 0; i < (int)coder.NumOutStreams; i++)
{
CMyComPtr<ISequentialOutStream> seqOutStream2;
RINOK(GetOutStream(outStreams, outSizes, startIndex + i, &seqOutStream2));
RINOK(setOutStream->SetOutStream(seqOutStream2));
}
*outStreamRes = seqOutStream.Detach();
return S_OK;
}
STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
if (numInStreams != (UInt32)_bindInfo.InStreams.Size() ||
numOutStreams != (UInt32)_bindInfo.OutStreams.Size())
return E_INVALIDARG;
// Find main coder
int _mainCoderIndex = -1;
int i;
for (i = 0; i < _coders.Size(); i++)
if (_coders[i].IsMain)
{
_mainCoderIndex = i;
break;
}
if (_mainCoderIndex < 0)
for (i = 0; i < _coders.Size(); i++)
if (_coders[i].NumInStreams > 1)
{
if (_mainCoderIndex >= 0)
return E_NOTIMPL;
_mainCoderIndex = i;
}
if (_mainCoderIndex < 0)
_mainCoderIndex = 0;
// _mainCoderIndex = 0;
// _mainCoderIndex = _coders.Size() - 1;
CCoderInfo &mainCoder = _coders[_mainCoderIndex];
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex);
UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex);
for (i = 0; i < (int)mainCoder.NumInStreams; i++)
{
CMyComPtr<ISequentialInStream> seqInStream;
RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream));
seqInStreams.Add(seqInStream);
}
for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
{
CMyComPtr<ISequentialOutStream> seqOutStream;
RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream));
seqOutStreams.Add(seqOutStream);
}
CRecordVector< ISequentialInStream * > seqInStreamsSpec;
CRecordVector< ISequentialOutStream * > seqOutStreamsSpec;
for (i = 0; i < (int)mainCoder.NumInStreams; i++)
seqInStreamsSpec.Add(seqInStreams[i]);
for (i = 0; i < (int)mainCoder.NumOutStreams; i++)
seqOutStreamsSpec.Add(seqOutStreams[i]);
for (i = 0; i < _coders.Size(); i++)
{
if (i == _mainCoderIndex)
continue;
CCoderInfo &coder = _coders[i];
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
if (setOutStreamSize)
{
RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0]));
}
}
if (mainCoder.Coder)
{
RINOK(mainCoder.Coder->Code(
seqInStreamsSpec[0], seqOutStreamsSpec[0],
mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0],
progress));
}
else
{
RINOK(mainCoder.Coder2->Code(
&seqInStreamsSpec.Front(),
&mainCoder.InSizePointers.Front(), mainCoder.NumInStreams,
&seqOutStreamsSpec.Front(),
&mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams,
progress));
}
CMyComPtr<IOutStreamFlush> flush;
seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush);
if (flush)
return flush->Flush();
return S_OK;
}
/*
UInt64 CCoderMixer2ST::GetWriteProcessedSize(UInt32 binderIndex) const
{
return _streamBinders[binderIndex].ProcessedSize;
}
*/
}