// 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 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 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 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 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 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 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 > seqInStreams; CObjectVector< CMyComPtr > seqOutStreams; UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex); UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex); for (i = 0; i < (int)mainCoder.NumInStreams; i++) { CMyComPtr seqInStream; RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream)); seqInStreams.Add(seqInStream); } for (i = 0; i < (int)mainCoder.NumOutStreams; i++) { CMyComPtr 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 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 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; } */ }