message: Multithread IPP gaussian blur
diff: @@ -2241,6 +2241,53 @@ static bool openvx_gaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
  #endif
  #ifdef HAVE_IPP
  +#define IPP_GAUSSIANBLUR_PARALLEL 1
  +
  +#ifdef HAVE_IPP_IW
  +
  +class ipp_gaussianBlurParallel: public ParallelLoopBody
  +{
  +public:
  + ipp_gaussianBlurParallel(::ipp::IwiImage &src, ::ipp::IwiImage &dst, int kernelSize, float sigma, ::ipp::IwiBorderType &border, bool *pOk):
  + m_src(src), m_dst(dst), m_kernelSize(kernelSize), m_sigma(sigma), m_border(border), m_pOk(pOk) {
  + *m_pOk = true;
  + }
  + ~ipp_gaussianBlurParallel()
  + {
  + }
  +
  + virtual void operator() (const Range& range) const
  + {
  + CV_INSTRUMENT_REGION_IPP()
  +
  + if(!*m_pOk)
  + return;
  +
  + try
  + {
  + ::ipp::IwiRoi roi = ::ipp::IwiRect(0, range.start, m_dst.m_size.width, range.end - range.start);
  + CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &m_src, &m_dst, m_kernelSize, m_sigma, m_border, &roi);
  + }
  + catch(::ipp::IwException e)
  + {
  + *m_pOk = false;
  + return;
  + }
  + }
  +private:
  + ::ipp::IwiImage &m_src;
  + ::ipp::IwiImage &m_dst;
  +
  + int m_kernelSize;
  + float m_sigma;
  + ::ipp::IwiBorderType &m_border;
  +
  + volatile bool *m_pOk;
  + const ipp_gaussianBlurParallel& operator= (const ipp_gaussianBlurParallel&);
  +};
  +
  +#endif
  +
  static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
  double sigma1, double sigma2, int borderType )
  {
  @@ -2272,7 +2319,26 @@ static bool ipp_GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
  if(!ippBorder.m_borderType)
  return false;
  - CV_INSTRUMENT_FUN_IPP(::ipp::iwiFilterGaussian, &iwSrc, &iwDst, ksize.width, (float)sigma1, ippBorder);
  + // IW 2017u2 has bug which doesn't allow use of partial inMem with tiling
  + if((((ippBorder.m_borderFlags)&ippBorderInMem) && ((ippBorder.m_borderFlags)&ippBorderInMem) != ippBorderInMem)) {
  + return false;
  + }
  +
  + bool ok;
  + ipp_gaussianBlurParallel invoker(iwSrc, iwDst, ksize.width, (float) sigma1, ippBorder, &ok);
  +
  + if(!ok)
  + return false;
  +
  + const Range range(0, (int) iwDst.m_size.height);
  + const int threads = ippiSuggestThreadsNum(iwDst, 2);
  + if(IPP_GAUSSIANBLUR_PARALLEL && threads > 1)
  + parallel_for_(range, invoker, threads*4);
  + else
  + invoker(range);
  +
  + if(!ok)
  + return false;
  }
  catch (::ipp::IwException ex)
  {
  