CoderMixer2.cpp (28161B)
1 // CoderMixer2.cpp 2 3 #include "StdAfx.h" 4 5 #include "CoderMixer2.h" 6 7 #ifdef USE_MIXER_ST 8 9 STDMETHODIMP CSequentialInStreamCalcSize::Read(void *data, UInt32 size, UInt32 *processedSize) 10 { 11 UInt32 realProcessed = 0; 12 HRESULT result = S_OK; 13 if (_stream) 14 result = _stream->Read(data, size, &realProcessed); 15 _size += realProcessed; 16 if (size != 0 && realProcessed == 0) 17 _wasFinished = true; 18 if (processedSize) 19 *processedSize = realProcessed; 20 return result; 21 } 22 23 24 STDMETHODIMP COutStreamCalcSize::Write(const void *data, UInt32 size, UInt32 *processedSize) 25 { 26 HRESULT result = S_OK; 27 if (_stream) 28 result = _stream->Write(data, size, &size); 29 _size += size; 30 if (processedSize) 31 *processedSize = size; 32 return result; 33 } 34 35 STDMETHODIMP COutStreamCalcSize::OutStreamFinish() 36 { 37 HRESULT result = S_OK; 38 if (_stream) 39 { 40 CMyComPtr<IOutStreamFinish> outStreamFinish; 41 _stream.QueryInterface(IID_IOutStreamFinish, &outStreamFinish); 42 if (outStreamFinish) 43 result = outStreamFinish->OutStreamFinish(); 44 } 45 return result; 46 } 47 48 #endif 49 50 51 52 53 namespace NCoderMixer2 { 54 55 static void BoolVector_Fill_False(CBoolVector &v, unsigned size) 56 { 57 v.ClearAndSetSize(size); 58 bool *p = &v[0]; 59 for (unsigned i = 0; i < size; i++) 60 p[i] = false; 61 } 62 63 64 HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPackSizeError */) const 65 { 66 if (Coder) 67 { 68 if (PackSizePointers.IsEmpty() || !PackSizePointers[0]) 69 return S_OK; 70 CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize; 71 Coder.QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize); 72 // if (!getInStreamProcessedSize) return E_FAIL; 73 if (getInStreamProcessedSize) 74 { 75 UInt64 processed; 76 RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed)); 77 if (processed != (UInt64)(Int64)-1) 78 { 79 const UInt64 size = PackSizes[0]; 80 if (processed < size && Finish) 81 dataAfterEnd_Error = true; 82 if (processed > size) 83 { 84 // InternalPackSizeError = true; 85 // return S_FALSE; 86 } 87 } 88 } 89 } 90 else if (Coder2) 91 { 92 CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2; 93 Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2); 94 FOR_VECTOR (i, PackSizePointers) 95 { 96 if (!PackSizePointers[i]) 97 continue; 98 UInt64 processed; 99 RINOK(getInStreamProcessedSize2->GetInStreamProcessedSize2(i, &processed)); 100 if (processed != (UInt64)(Int64)-1) 101 { 102 const UInt64 size = PackSizes[i]; 103 if (processed < size && Finish) 104 dataAfterEnd_Error = true; 105 else if (processed > size) 106 { 107 // InternalPackSizeError = true; 108 // return S_FALSE; 109 } 110 } 111 } 112 } 113 114 return S_OK; 115 } 116 117 118 119 class CBondsChecks 120 { 121 CBoolVector _coderUsed; 122 123 bool Init(); 124 bool CheckCoder(unsigned coderIndex); 125 public: 126 const CBindInfo *BindInfo; 127 128 bool Check(); 129 }; 130 131 bool CBondsChecks::CheckCoder(unsigned coderIndex) 132 { 133 const CCoderStreamsInfo &coder = BindInfo->Coders[coderIndex]; 134 135 if (coderIndex >= _coderUsed.Size() || _coderUsed[coderIndex]) 136 return false; 137 _coderUsed[coderIndex] = true; 138 139 UInt32 start = BindInfo->Coder_to_Stream[coderIndex]; 140 141 for (unsigned i = 0; i < coder.NumStreams; i++) 142 { 143 UInt32 ind = start + i; 144 145 if (BindInfo->IsStream_in_PackStreams(ind)) 146 continue; 147 148 int bond = BindInfo->FindBond_for_PackStream(ind); 149 if (bond < 0) 150 return false; 151 if (!CheckCoder(BindInfo->Bonds[bond].UnpackIndex)) 152 return false; 153 } 154 155 return true; 156 } 157 158 bool CBondsChecks::Check() 159 { 160 BoolVector_Fill_False(_coderUsed, BindInfo->Coders.Size()); 161 162 if (!CheckCoder(BindInfo->UnpackCoder)) 163 return false; 164 165 FOR_VECTOR(i, _coderUsed) 166 if (!_coderUsed[i]) 167 return false; 168 169 return true; 170 } 171 172 void CBindInfo::ClearMaps() 173 { 174 Coder_to_Stream.Clear(); 175 Stream_to_Coder.Clear(); 176 } 177 178 bool CBindInfo::CalcMapsAndCheck() 179 { 180 ClearMaps(); 181 182 UInt32 numStreams = 0; 183 184 if (Coders.Size() == 0) 185 return false; 186 if (Coders.Size() - 1 != Bonds.Size()) 187 return false; 188 189 FOR_VECTOR(i, Coders) 190 { 191 Coder_to_Stream.Add(numStreams); 192 193 const CCoderStreamsInfo &c = Coders[i]; 194 195 for (unsigned j = 0; j < c.NumStreams; j++) 196 Stream_to_Coder.Add(i); 197 198 numStreams += c.NumStreams; 199 } 200 201 if (numStreams != GetNum_Bonds_and_PackStreams()) 202 return false; 203 204 CBondsChecks bc; 205 bc.BindInfo = this; 206 return bc.Check(); 207 } 208 209 210 void CCoder::SetCoderInfo(const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) 211 { 212 Finish = finish; 213 214 if (unpackSize) 215 { 216 UnpackSize = *unpackSize; 217 UnpackSizePointer = &UnpackSize; 218 } 219 else 220 { 221 UnpackSize = 0; 222 UnpackSizePointer = NULL; 223 } 224 225 PackSizes.ClearAndSetSize((unsigned)NumStreams); 226 PackSizePointers.ClearAndSetSize((unsigned)NumStreams); 227 228 for (unsigned i = 0; i < NumStreams; i++) 229 { 230 if (packSizes && packSizes[i]) 231 { 232 PackSizes[i] = *(packSizes[i]); 233 PackSizePointers[i] = &PackSizes[i]; 234 } 235 else 236 { 237 PackSizes[i] = 0; 238 PackSizePointers[i] = NULL; 239 } 240 } 241 } 242 243 bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex) 244 { 245 if (coderIndex == _bi.UnpackCoder) 246 return true; 247 248 int bond = _bi.FindBond_for_UnpackStream(coderIndex); 249 if (bond < 0) 250 throw 20150213; 251 252 /* 253 UInt32 coderIndex, coderStreamIndex; 254 _bi.GetCoder_for_Stream(_bi.Bonds[bond].PackIndex, coderIndex, coderStreamIndex); 255 */ 256 UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[bond].PackIndex]; 257 258 if (!IsFilter_Vector[nextCoder]) 259 return false; 260 261 return Is_UnpackSize_Correct_for_Coder(nextCoder); 262 } 263 264 bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex) 265 { 266 if (_bi.IsStream_in_PackStreams(streamIndex)) 267 return true; 268 269 int bond = _bi.FindBond_for_PackStream(streamIndex); 270 if (bond < 0) 271 throw 20150213; 272 273 UInt32 nextCoder = _bi.Bonds[bond].UnpackIndex; 274 275 if (!IsFilter_Vector[nextCoder]) 276 return false; 277 278 return Is_PackSize_Correct_for_Coder(nextCoder); 279 } 280 281 bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex) 282 { 283 UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; 284 UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; 285 for (UInt32 i = 0; i < numStreams; i++) 286 if (!Is_PackSize_Correct_for_Stream(startIndex + i)) 287 return false; 288 return true; 289 } 290 291 bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex) 292 { 293 if (IsExternal_Vector[coderIndex]) 294 return true; 295 UInt32 startIndex = _bi.Coder_to_Stream[coderIndex]; 296 UInt32 numStreams = _bi.Coders[coderIndex].NumStreams; 297 for (UInt32 i = 0; i < numStreams; i++) 298 { 299 UInt32 si = startIndex + i; 300 if (_bi.IsStream_in_PackStreams(si)) 301 continue; 302 303 int bond = _bi.FindBond_for_PackStream(si); 304 if (bond < 0) 305 throw 20150213; 306 307 if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[bond].UnpackIndex)) 308 return true; 309 } 310 return false; 311 } 312 313 314 315 316 #ifdef USE_MIXER_ST 317 318 CMixerST::CMixerST(bool encodeMode): 319 CMixer(encodeMode) 320 {} 321 322 CMixerST::~CMixerST() {} 323 324 void CMixerST::AddCoder(const CCreatedCoder &cod) 325 { 326 IsFilter_Vector.Add(cod.IsFilter); 327 IsExternal_Vector.Add(cod.IsExternal); 328 // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()]; 329 CCoderST &c2 = _coders.AddNew(); 330 c2.NumStreams = cod.NumStreams; 331 c2.Coder = cod.Coder; 332 c2.Coder2 = cod.Coder2; 333 334 /* 335 if (isFilter) 336 { 337 c2.CanRead = true; 338 c2.CanWrite = true; 339 } 340 else 341 */ 342 { 343 IUnknown *unk = (cod.Coder ? (IUnknown *)cod.Coder : (IUnknown *)cod.Coder2); 344 { 345 CMyComPtr<ISequentialInStream> s; 346 unk->QueryInterface(IID_ISequentialInStream, (void**)&s); 347 c2.CanRead = (s != NULL); 348 } 349 { 350 CMyComPtr<ISequentialOutStream> s; 351 unk->QueryInterface(IID_ISequentialOutStream, (void**)&s); 352 c2.CanWrite = (s != NULL); 353 } 354 } 355 } 356 357 CCoder &CMixerST::GetCoder(unsigned index) 358 { 359 return _coders[index]; 360 } 361 362 void CMixerST::ReInit() {} 363 364 HRESULT CMixerST::GetInStream2( 365 ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ 366 UInt32 outStreamIndex, ISequentialInStream **inStreamRes) 367 { 368 UInt32 coderIndex = outStreamIndex, coderStreamIndex = 0; 369 370 if (EncodeMode) 371 { 372 _bi.GetCoder_for_Stream(outStreamIndex, coderIndex, coderStreamIndex); 373 if (coderStreamIndex != 0) 374 return E_NOTIMPL; 375 } 376 377 const CCoder &coder = _coders[coderIndex]; 378 379 CMyComPtr<ISequentialInStream> seqInStream; 380 coder.QueryInterface(IID_ISequentialInStream, (void **)&seqInStream); 381 if (!seqInStream) 382 return E_NOTIMPL; 383 384 UInt32 numInStreams = EncodeMode ? 1 : coder.NumStreams; 385 UInt32 startIndex = EncodeMode ? coderIndex : _bi.Coder_to_Stream[coderIndex]; 386 387 bool isSet = false; 388 389 if (numInStreams == 1) 390 { 391 CMyComPtr<ICompressSetInStream> setStream; 392 coder.QueryInterface(IID_ICompressSetInStream, (void **)&setStream); 393 if (setStream) 394 { 395 CMyComPtr<ISequentialInStream> seqInStream2; 396 RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + 0, &seqInStream2)); 397 RINOK(setStream->SetInStream(seqInStream2)); 398 isSet = true; 399 } 400 } 401 402 if (!isSet && numInStreams != 0) 403 { 404 CMyComPtr<ICompressSetInStream2> setStream2; 405 coder.QueryInterface(IID_ICompressSetInStream2, (void **)&setStream2); 406 if (!setStream2) 407 return E_NOTIMPL; 408 409 for (UInt32 i = 0; i < numInStreams; i++) 410 { 411 CMyComPtr<ISequentialInStream> seqInStream2; 412 RINOK(GetInStream(inStreams, /* inSizes, */ startIndex + i, &seqInStream2)); 413 RINOK(setStream2->SetInStream2(i, seqInStream2)); 414 } 415 } 416 417 *inStreamRes = seqInStream.Detach(); 418 return S_OK; 419 } 420 421 422 HRESULT CMixerST::GetInStream( 423 ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */ 424 UInt32 inStreamIndex, ISequentialInStream **inStreamRes) 425 { 426 CMyComPtr<ISequentialInStream> seqInStream; 427 428 { 429 int index = -1; 430 if (EncodeMode) 431 { 432 if (_bi.UnpackCoder == inStreamIndex) 433 index = 0; 434 } 435 else 436 index = _bi.FindStream_in_PackStreams(inStreamIndex); 437 438 if (index >= 0) 439 { 440 seqInStream = inStreams[(unsigned)index]; 441 *inStreamRes = seqInStream.Detach(); 442 return S_OK; 443 } 444 } 445 446 int bond = FindBond_for_Stream( 447 true, // forInputStream 448 inStreamIndex); 449 if (bond < 0) 450 return E_INVALIDARG; 451 452 RINOK(GetInStream2(inStreams, /* inSizes, */ 453 _bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream)); 454 455 while (_binderStreams.Size() <= (unsigned)bond) 456 _binderStreams.AddNew(); 457 CStBinderStream &bs = _binderStreams[bond]; 458 459 if (bs.StreamRef || bs.InStreamSpec) 460 return E_NOTIMPL; 461 462 CSequentialInStreamCalcSize *spec = new CSequentialInStreamCalcSize; 463 bs.StreamRef = spec; 464 bs.InStreamSpec = spec; 465 466 spec->SetStream(seqInStream); 467 spec->Init(); 468 469 seqInStream = bs.InStreamSpec; 470 471 *inStreamRes = seqInStream.Detach(); 472 return S_OK; 473 } 474 475 476 HRESULT CMixerST::GetOutStream( 477 ISequentialOutStream * const *outStreams, /* const UInt64 * const *outSizes, */ 478 UInt32 outStreamIndex, ISequentialOutStream **outStreamRes) 479 { 480 CMyComPtr<ISequentialOutStream> seqOutStream; 481 482 { 483 int index = -1; 484 if (!EncodeMode) 485 { 486 if (_bi.UnpackCoder == outStreamIndex) 487 index = 0; 488 } 489 else 490 index = _bi.FindStream_in_PackStreams(outStreamIndex); 491 492 if (index >= 0) 493 { 494 seqOutStream = outStreams[(unsigned)index]; 495 *outStreamRes = seqOutStream.Detach(); 496 return S_OK; 497 } 498 } 499 500 int bond = FindBond_for_Stream( 501 false, // forInputStream 502 outStreamIndex); 503 if (bond < 0) 504 return E_INVALIDARG; 505 506 UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode); 507 508 UInt32 coderIndex = inStreamIndex; 509 UInt32 coderStreamIndex = 0; 510 511 if (!EncodeMode) 512 _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex); 513 514 CCoder &coder = _coders[coderIndex]; 515 516 /* 517 if (!coder.Coder) 518 return E_NOTIMPL; 519 */ 520 521 coder.QueryInterface(IID_ISequentialOutStream, (void **)&seqOutStream); 522 if (!seqOutStream) 523 return E_NOTIMPL; 524 525 UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; 526 UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; 527 528 bool isSet = false; 529 530 if (numOutStreams == 1) 531 { 532 CMyComPtr<ICompressSetOutStream> setOutStream; 533 coder.Coder.QueryInterface(IID_ICompressSetOutStream, &setOutStream); 534 if (setOutStream) 535 { 536 CMyComPtr<ISequentialOutStream> seqOutStream2; 537 RINOK(GetOutStream(outStreams, /* outSizes, */ startIndex + 0, &seqOutStream2)); 538 RINOK(setOutStream->SetOutStream(seqOutStream2)); 539 isSet = true; 540 } 541 } 542 543 if (!isSet && numOutStreams != 0) 544 { 545 return E_NOTIMPL; 546 /* 547 CMyComPtr<ICompressSetOutStream2> setStream2; 548 coder.QueryInterface(IID_ICompressSetOutStream2, (void **)&setStream2); 549 if (!setStream2) 550 return E_NOTIMPL; 551 for (UInt32 i = 0; i < numOutStreams; i++) 552 { 553 CMyComPtr<ISequentialOutStream> seqOutStream2; 554 RINOK(GetOutStream(outStreams, startIndex + i, &seqOutStream2)); 555 RINOK(setStream2->SetOutStream2(i, seqOutStream2)); 556 } 557 */ 558 } 559 560 while (_binderStreams.Size() <= (unsigned)bond) 561 _binderStreams.AddNew(); 562 CStBinderStream &bs = _binderStreams[bond]; 563 564 if (bs.StreamRef || bs.OutStreamSpec) 565 return E_NOTIMPL; 566 567 COutStreamCalcSize *spec = new COutStreamCalcSize; 568 bs.StreamRef = (ISequentialOutStream *)spec; 569 bs.OutStreamSpec = spec; 570 571 spec->SetStream(seqOutStream); 572 spec->Init(); 573 574 seqOutStream = bs.OutStreamSpec; 575 576 *outStreamRes = seqOutStream.Detach(); 577 return S_OK; 578 } 579 580 581 static HRESULT GetError(HRESULT res, HRESULT res2) 582 { 583 if (res == res2) 584 return res; 585 if (res == S_OK) 586 return res2; 587 if (res == k_My_HRESULT_WritingWasCut) 588 { 589 if (res2 != S_OK) 590 return res2; 591 } 592 return res; 593 } 594 595 596 HRESULT CMixerST::FinishStream(UInt32 streamIndex) 597 { 598 { 599 int index = -1; 600 if (!EncodeMode) 601 { 602 if (_bi.UnpackCoder == streamIndex) 603 index = 0; 604 } 605 else 606 index = _bi.FindStream_in_PackStreams(streamIndex); 607 608 if (index >= 0) 609 return S_OK; 610 } 611 612 int bond = FindBond_for_Stream( 613 false, // forInputStream 614 streamIndex); 615 if (bond < 0) 616 return E_INVALIDARG; 617 618 UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode); 619 620 UInt32 coderIndex = inStreamIndex; 621 UInt32 coderStreamIndex = 0; 622 if (!EncodeMode) 623 _bi.GetCoder_for_Stream(inStreamIndex, coderIndex, coderStreamIndex); 624 625 CCoder &coder = _coders[coderIndex]; 626 CMyComPtr<IOutStreamFinish> finish; 627 coder.QueryInterface(IID_IOutStreamFinish, (void **)&finish); 628 HRESULT res = S_OK; 629 if (finish) 630 { 631 res = finish->OutStreamFinish(); 632 } 633 return GetError(res, FinishCoder(coderIndex)); 634 } 635 636 637 HRESULT CMixerST::FinishCoder(UInt32 coderIndex) 638 { 639 CCoder &coder = _coders[coderIndex]; 640 641 UInt32 numOutStreams = EncodeMode ? coder.NumStreams : 1; 642 UInt32 startIndex = EncodeMode ? _bi.Coder_to_Stream[coderIndex]: coderIndex; 643 644 HRESULT res = S_OK; 645 for (unsigned i = 0; i < numOutStreams; i++) 646 res = GetError(res, FinishStream(startIndex + i)); 647 return res; 648 } 649 650 651 void CMixerST::SelectMainCoder(bool useFirst) 652 { 653 unsigned ci = _bi.UnpackCoder; 654 655 int firstNonFilter = -1; 656 int firstAllowed = ci; 657 658 for (;;) 659 { 660 const CCoderST &coder = _coders[ci]; 661 // break; 662 663 if (ci != _bi.UnpackCoder) 664 if (EncodeMode ? !coder.CanWrite : !coder.CanRead) 665 { 666 firstAllowed = ci; 667 firstNonFilter = -2; 668 } 669 670 if (coder.NumStreams != 1) 671 break; 672 673 UInt32 st = _bi.Coder_to_Stream[ci]; 674 if (_bi.IsStream_in_PackStreams(st)) 675 break; 676 int bond = _bi.FindBond_for_PackStream(st); 677 if (bond < 0) 678 throw 20150213; 679 680 if (EncodeMode ? !coder.CanRead : !coder.CanWrite) 681 break; 682 683 if (firstNonFilter == -1 && !IsFilter_Vector[ci]) 684 firstNonFilter = ci; 685 686 ci = _bi.Bonds[bond].UnpackIndex; 687 } 688 689 if (useFirst) 690 ci = firstAllowed; 691 else if (firstNonFilter >= 0) 692 ci = firstNonFilter; 693 694 MainCoderIndex = ci; 695 } 696 697 698 HRESULT CMixerST::Code( 699 ISequentialInStream * const *inStreams, 700 ISequentialOutStream * const *outStreams, 701 ICompressProgressInfo *progress, 702 bool &dataAfterEnd_Error) 703 { 704 // InternalPackSizeError = false; 705 dataAfterEnd_Error = false; 706 707 _binderStreams.Clear(); 708 unsigned ci = MainCoderIndex; 709 710 const CCoder &mainCoder = _coders[MainCoderIndex]; 711 712 CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams; 713 CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams; 714 715 UInt32 numInStreams = EncodeMode ? 1 : mainCoder.NumStreams; 716 UInt32 numOutStreams = !EncodeMode ? 1 : mainCoder.NumStreams; 717 718 UInt32 startInIndex = EncodeMode ? ci : _bi.Coder_to_Stream[ci]; 719 UInt32 startOutIndex = !EncodeMode ? ci : _bi.Coder_to_Stream[ci]; 720 721 UInt32 i; 722 723 for (i = 0; i < numInStreams; i++) 724 { 725 CMyComPtr<ISequentialInStream> seqInStream; 726 RINOK(GetInStream(inStreams, /* inSizes, */ startInIndex + i, &seqInStream)); 727 seqInStreams.Add(seqInStream); 728 } 729 730 for (i = 0; i < numOutStreams; i++) 731 { 732 CMyComPtr<ISequentialOutStream> seqOutStream; 733 RINOK(GetOutStream(outStreams, /* outSizes, */ startOutIndex + i, &seqOutStream)); 734 seqOutStreams.Add(seqOutStream); 735 } 736 737 CRecordVector< ISequentialInStream * > seqInStreamsSpec; 738 CRecordVector< ISequentialOutStream * > seqOutStreamsSpec; 739 740 for (i = 0; i < numInStreams; i++) 741 seqInStreamsSpec.Add(seqInStreams[i]); 742 for (i = 0; i < numOutStreams; i++) 743 seqOutStreamsSpec.Add(seqOutStreams[i]); 744 745 for (i = 0; i < _coders.Size(); i++) 746 { 747 if (i == ci) 748 continue; 749 750 CCoder &coder = _coders[i]; 751 752 if (EncodeMode) 753 { 754 CMyComPtr<ICompressInitEncoder> initEncoder; 755 coder.QueryInterface(IID_ICompressInitEncoder, (void **)&initEncoder); 756 if (initEncoder) 757 RINOK(initEncoder->InitEncoder()); 758 } 759 else 760 { 761 CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; 762 coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); 763 if (setOutStreamSize) 764 RINOK(setOutStreamSize->SetOutStreamSize( 765 EncodeMode ? coder.PackSizePointers[0] : coder.UnpackSizePointer)); 766 } 767 } 768 769 const UInt64 * const *isSizes2 = EncodeMode ? &mainCoder.UnpackSizePointer : &mainCoder.PackSizePointers.Front(); 770 const UInt64 * const *outSizes2 = EncodeMode ? &mainCoder.PackSizePointers.Front() : &mainCoder.UnpackSizePointer; 771 772 HRESULT res; 773 if (mainCoder.Coder) 774 { 775 res = mainCoder.Coder->Code( 776 seqInStreamsSpec[0], seqOutStreamsSpec[0], 777 isSizes2[0], outSizes2[0], 778 progress); 779 } 780 else 781 { 782 res = mainCoder.Coder2->Code( 783 &seqInStreamsSpec.Front(), isSizes2, numInStreams, 784 &seqOutStreamsSpec.Front(), outSizes2, numOutStreams, 785 progress); 786 } 787 788 if (res == k_My_HRESULT_WritingWasCut) 789 res = S_OK; 790 791 if (res == S_OK || res == S_FALSE) 792 { 793 res = GetError(res, FinishCoder(ci)); 794 } 795 796 for (i = 0; i < _binderStreams.Size(); i++) 797 { 798 const CStBinderStream &bs = _binderStreams[i]; 799 if (bs.InStreamSpec) 800 bs.InStreamSpec->ReleaseStream(); 801 else 802 bs.OutStreamSpec->ReleaseStream(); 803 } 804 805 if (res == k_My_HRESULT_WritingWasCut) 806 res = S_OK; 807 808 if (res != S_OK) 809 return res; 810 811 for (i = 0; i < _coders.Size(); i++) 812 { 813 RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /*, InternalPackSizeError */)); 814 } 815 816 return S_OK; 817 } 818 819 820 HRESULT CMixerST::GetMainUnpackStream( 821 ISequentialInStream * const *inStreams, 822 ISequentialInStream **inStreamRes) 823 { 824 CMyComPtr<ISequentialInStream> seqInStream; 825 826 RINOK(GetInStream2(inStreams, /* inSizes, */ 827 _bi.UnpackCoder, &seqInStream)) 828 829 FOR_VECTOR (i, _coders) 830 { 831 CCoder &coder = _coders[i]; 832 CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; 833 coder.QueryInterface(IID_ICompressSetOutStreamSize, (void **)&setOutStreamSize); 834 if (setOutStreamSize) 835 { 836 RINOK(setOutStreamSize->SetOutStreamSize(coder.UnpackSizePointer)); 837 } 838 } 839 840 *inStreamRes = seqInStream.Detach(); 841 return S_OK; 842 } 843 844 845 UInt64 CMixerST::GetBondStreamSize(unsigned bondIndex) const 846 { 847 const CStBinderStream &bs = _binderStreams[bondIndex]; 848 if (bs.InStreamSpec) 849 return bs.InStreamSpec->GetSize(); 850 return bs.OutStreamSpec->GetSize(); 851 } 852 853 #endif 854 855 856 857 858 859 860 #ifdef USE_MIXER_MT 861 862 863 void CCoderMT::Execute() 864 { 865 try 866 { 867 Code(NULL); 868 } 869 catch(...) 870 { 871 Result = E_FAIL; 872 } 873 } 874 875 void CCoderMT::Code(ICompressProgressInfo *progress) 876 { 877 unsigned numInStreams = EncodeMode ? 1 : NumStreams; 878 unsigned numOutStreams = EncodeMode ? NumStreams : 1; 879 880 InStreamPointers.ClearAndReserve(numInStreams); 881 OutStreamPointers.ClearAndReserve(numOutStreams); 882 883 unsigned i; 884 885 for (i = 0; i < numInStreams; i++) 886 InStreamPointers.AddInReserved((ISequentialInStream *)InStreams[i]); 887 888 for (i = 0; i < numOutStreams; i++) 889 OutStreamPointers.AddInReserved((ISequentialOutStream *)OutStreams[i]); 890 891 // we suppose that UnpackSizePointer and PackSizePointers contain correct pointers. 892 /* 893 if (UnpackSizePointer) 894 UnpackSizePointer = &UnpackSize; 895 for (i = 0; i < NumStreams; i++) 896 if (PackSizePointers[i]) 897 PackSizePointers[i] = &PackSizes[i]; 898 */ 899 900 CReleaser releaser(*this); 901 902 if (Coder) 903 Result = Coder->Code(InStreamPointers[0], OutStreamPointers[0], 904 EncodeMode ? UnpackSizePointer : PackSizePointers[0], 905 EncodeMode ? PackSizePointers[0] : UnpackSizePointer, 906 progress); 907 else 908 Result = Coder2->Code( 909 &InStreamPointers.Front(), EncodeMode ? &UnpackSizePointer : &PackSizePointers.Front(), numInStreams, 910 &OutStreamPointers.Front(), EncodeMode ? &PackSizePointers.Front(): &UnpackSizePointer, numOutStreams, 911 progress); 912 } 913 914 HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo) 915 { 916 CMixer::SetBindInfo(bindInfo); 917 918 _streamBinders.Clear(); 919 FOR_VECTOR (i, _bi.Bonds) 920 { 921 RINOK(_streamBinders.AddNew().CreateEvents()); 922 } 923 return S_OK; 924 } 925 926 void CMixerMT::AddCoder(const CCreatedCoder &cod) 927 { 928 IsFilter_Vector.Add(cod.IsFilter); 929 IsExternal_Vector.Add(cod.IsExternal); 930 // const CCoderStreamsInfo &c = _bi.Coders[_coders.Size()]; 931 CCoderMT &c2 = _coders.AddNew(); 932 c2.NumStreams = cod.NumStreams; 933 c2.Coder = cod.Coder; 934 c2.Coder2 = cod.Coder2; 935 c2.EncodeMode = EncodeMode; 936 } 937 938 CCoder &CMixerMT::GetCoder(unsigned index) 939 { 940 return _coders[index]; 941 } 942 943 void CMixerMT::ReInit() 944 { 945 FOR_VECTOR (i, _streamBinders) 946 _streamBinders[i].ReInit(); 947 } 948 949 void CMixerMT::SelectMainCoder(bool useFirst) 950 { 951 unsigned ci = _bi.UnpackCoder; 952 953 if (!useFirst) 954 for (;;) 955 { 956 if (_coders[ci].NumStreams != 1) 957 break; 958 if (!IsFilter_Vector[ci]) 959 break; 960 961 UInt32 st = _bi.Coder_to_Stream[ci]; 962 if (_bi.IsStream_in_PackStreams(st)) 963 break; 964 int bond = _bi.FindBond_for_PackStream(st); 965 if (bond < 0) 966 throw 20150213; 967 ci = _bi.Bonds[bond].UnpackIndex; 968 } 969 970 MainCoderIndex = ci; 971 } 972 973 HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams) 974 { 975 unsigned i; 976 977 for (i = 0; i < _coders.Size(); i++) 978 { 979 CCoderMT &coderInfo = _coders[i]; 980 const CCoderStreamsInfo &csi = _bi.Coders[i]; 981 982 UInt32 j; 983 984 unsigned numInStreams = EncodeMode ? 1 : csi.NumStreams; 985 unsigned numOutStreams = EncodeMode ? csi.NumStreams : 1; 986 987 coderInfo.InStreams.Clear(); 988 for (j = 0; j < numInStreams; j++) 989 coderInfo.InStreams.AddNew(); 990 991 coderInfo.OutStreams.Clear(); 992 for (j = 0; j < numOutStreams; j++) 993 coderInfo.OutStreams.AddNew(); 994 } 995 996 for (i = 0; i < _bi.Bonds.Size(); i++) 997 { 998 const CBond &bond = _bi.Bonds[i]; 999 1000 UInt32 inCoderIndex, inCoderStreamIndex; 1001 UInt32 outCoderIndex, outCoderStreamIndex; 1002 1003 { 1004 UInt32 coderIndex, coderStreamIndex; 1005 _bi.GetCoder_for_Stream(bond.PackIndex, coderIndex, coderStreamIndex); 1006 1007 inCoderIndex = EncodeMode ? bond.UnpackIndex : coderIndex; 1008 outCoderIndex = EncodeMode ? coderIndex : bond.UnpackIndex; 1009 1010 inCoderStreamIndex = EncodeMode ? 0 : coderStreamIndex; 1011 outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0; 1012 } 1013 1014 _streamBinders[i].CreateStreams( 1015 &_coders[inCoderIndex].InStreams[inCoderStreamIndex], 1016 &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]); 1017 1018 CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize; 1019 _coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize); 1020 _coders[outCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&outSetSize); 1021 if (inSetSize && outSetSize) 1022 { 1023 const UInt32 kBufSize = 1 << 19; 1024 inSetSize->SetInBufSize(inCoderStreamIndex, kBufSize); 1025 outSetSize->SetOutBufSize(outCoderStreamIndex, kBufSize); 1026 } 1027 } 1028 1029 { 1030 CCoderMT &cod = _coders[_bi.UnpackCoder]; 1031 if (EncodeMode) 1032 cod.InStreams[0] = inStreams[0]; 1033 else 1034 cod.OutStreams[0] = outStreams[0]; 1035 } 1036 1037 for (i = 0; i < _bi.PackStreams.Size(); i++) 1038 { 1039 UInt32 coderIndex, coderStreamIndex; 1040 _bi.GetCoder_for_Stream(_bi.PackStreams[i], coderIndex, coderStreamIndex); 1041 CCoderMT &cod = _coders[coderIndex]; 1042 if (EncodeMode) 1043 cod.OutStreams[coderStreamIndex] = outStreams[i]; 1044 else 1045 cod.InStreams[coderStreamIndex] = inStreams[i]; 1046 } 1047 1048 return S_OK; 1049 } 1050 1051 HRESULT CMixerMT::ReturnIfError(HRESULT code) 1052 { 1053 FOR_VECTOR (i, _coders) 1054 if (_coders[i].Result == code) 1055 return code; 1056 return S_OK; 1057 } 1058 1059 HRESULT CMixerMT::Code( 1060 ISequentialInStream * const *inStreams, 1061 ISequentialOutStream * const *outStreams, 1062 ICompressProgressInfo *progress, 1063 bool &dataAfterEnd_Error) 1064 { 1065 // InternalPackSizeError = false; 1066 dataAfterEnd_Error = false; 1067 1068 Init(inStreams, outStreams); 1069 1070 unsigned i; 1071 for (i = 0; i < _coders.Size(); i++) 1072 if (i != MainCoderIndex) 1073 { 1074 RINOK(_coders[i].Create()); 1075 } 1076 1077 for (i = 0; i < _coders.Size(); i++) 1078 if (i != MainCoderIndex) 1079 _coders[i].Start(); 1080 1081 _coders[MainCoderIndex].Code(progress); 1082 1083 for (i = 0; i < _coders.Size(); i++) 1084 if (i != MainCoderIndex) 1085 _coders[i].WaitExecuteFinish(); 1086 1087 RINOK(ReturnIfError(E_ABORT)); 1088 RINOK(ReturnIfError(E_OUTOFMEMORY)); 1089 1090 for (i = 0; i < _coders.Size(); i++) 1091 { 1092 HRESULT result = _coders[i].Result; 1093 if (result != S_OK 1094 && result != k_My_HRESULT_WritingWasCut 1095 && result != S_FALSE 1096 && result != E_FAIL) 1097 return result; 1098 } 1099 1100 RINOK(ReturnIfError(S_FALSE)); 1101 1102 for (i = 0; i < _coders.Size(); i++) 1103 { 1104 HRESULT result = _coders[i].Result; 1105 if (result != S_OK && result != k_My_HRESULT_WritingWasCut) 1106 return result; 1107 } 1108 1109 for (i = 0; i < _coders.Size(); i++) 1110 { 1111 RINOK(_coders[i].CheckDataAfterEnd(dataAfterEnd_Error /* , InternalPackSizeError */)); 1112 } 1113 1114 return S_OK; 1115 } 1116 1117 UInt64 CMixerMT::GetBondStreamSize(unsigned bondIndex) const 1118 { 1119 return _streamBinders[bondIndex].ProcessedSize; 1120 } 1121 1122 #endif 1123 1124 }