Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/AnnexBwrite.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/AnnexBwrite.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/AnnexBwrite.h	(revision 1360)
@@ -60,5 +60,5 @@
     UInt size = 0; /* size of annexB unit in bytes */
 
-    static const Char start_code_prefix[] = {0,0,0,1};
+    static const UChar start_code_prefix[] = {0,0,0,1};
     if (it == au.begin() || nalu.m_nalUnitType == NAL_UNIT_VPS || nalu.m_nalUnitType == NAL_UNIT_SPS || nalu.m_nalUnitType == NAL_UNIT_PPS)
     {
@@ -71,10 +71,10 @@
        *    7.4.1.2.3.
        */
-      out.write(start_code_prefix, 4);
+      out.write(reinterpret_cast<const TChar*>(start_code_prefix), 4);
       size += 4;
     }
     else
     {
-      out.write(start_code_prefix+1, 3);
+      out.write(reinterpret_cast<const TChar*>(start_code_prefix+1), 3);
       size += 3;
     }
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/NALwrite.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/NALwrite.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/NALwrite.cpp	(revision 1360)
@@ -45,5 +45,5 @@
 //! \{
 
-static const Char emulation_prevention_three_byte[] = {3};
+static const UChar emulation_prevention_three_byte[] = {3};
 
 Void writeNalUnitHeader(ostream& out, OutputNALUnit& nalu)       // nal_unit_header()
@@ -60,5 +60,5 @@
   bsNALUHeader.write(nalu.m_temporalId+1, 3); // nuh_temporal_id_plus1
 
-  out.write(bsNALUHeader.getByteStream(), bsNALUHeader.getByteStreamLength());
+  out.write(reinterpret_cast<const TChar*>(bsNALUHeader.getByteStream()), bsNALUHeader.getByteStreamLength());
 }
 /**
@@ -124,5 +124,5 @@
     outputBuffer[outputAmount++]=emulation_prevention_three_byte[0];
   }
-  out.write((Char*)&(*outputBuffer.begin()), outputAmount);
+  out.write(reinterpret_cast<const TChar*>(&(*outputBuffer.begin())), outputAmount);
 }
 
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.cpp	(revision 1360)
@@ -294,21 +294,26 @@
   assert (pcPic!=NULL);
 
-  if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
-  {
-    decodedPictureHashSEI->method = SEIDecodedPictureHash::MD5;
+  decodedPictureHashSEI->method = m_pcCfg->getDecodedPictureHashSEIType();
+  switch (m_pcCfg->getDecodedPictureHashSEIType())
+  {
+    case HASHTYPE_MD5:
+  {
     UInt numChar=calcMD5(*pcPic->getPicYuvRec(), decodedPictureHashSEI->m_pictureHash, bitDepths);
     rHashString = hashToString(decodedPictureHashSEI->m_pictureHash, numChar);
   }
-  else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
-  {
-    decodedPictureHashSEI->method = SEIDecodedPictureHash::CRC;
+      break;
+    case HASHTYPE_CRC:
+  {
     UInt numChar=calcCRC(*pcPic->getPicYuvRec(), decodedPictureHashSEI->m_pictureHash, bitDepths);
     rHashString = hashToString(decodedPictureHashSEI->m_pictureHash, numChar);
   }
-  else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
-  {
-    decodedPictureHashSEI->method = SEIDecodedPictureHash::CHECKSUM;
+      break;
+    case HASHTYPE_CHECKSUM:
+    default:
+  {
     UInt numChar=calcChecksum(*pcPic->getPicYuvRec(), decodedPictureHashSEI->m_pictureHash, bitDepths);
     rHashString = hashToString(decodedPictureHashSEI->m_pictureHash, numChar);
+  }
+      break;
   }
 }
@@ -397,56 +402,239 @@
   }
 }
-
-Void SEIEncoder::initSEIChromaSamplingFilterHint(SEIChromaSamplingFilterHint *seiChromaSamplingFilterHint, Int iHorFilterIndex, Int iVerFilterIndex)
-{
-  assert (m_isInitialized);
-  assert (seiChromaSamplingFilterHint!=NULL);
-
-  seiChromaSamplingFilterHint->m_verChromaFilterIdc = iVerFilterIndex;
-  seiChromaSamplingFilterHint->m_horChromaFilterIdc = iHorFilterIndex;
-  seiChromaSamplingFilterHint->m_verFilteringProcessFlag = 1;
-  seiChromaSamplingFilterHint->m_targetFormatIdc = 3;
-  seiChromaSamplingFilterHint->m_perfectReconstructionFlag = false;
-  if(seiChromaSamplingFilterHint->m_verChromaFilterIdc == 1)
-  {
-    seiChromaSamplingFilterHint->m_numVerticalFilters = 1;
-    seiChromaSamplingFilterHint->m_verTapLengthMinus1 = (Int*)malloc(seiChromaSamplingFilterHint->m_numVerticalFilters * sizeof(Int));
-    seiChromaSamplingFilterHint->m_verFilterCoeff =    (Int**)malloc(seiChromaSamplingFilterHint->m_numVerticalFilters * sizeof(Int*));
-    for(Int i = 0; i < seiChromaSamplingFilterHint->m_numVerticalFilters; i ++)
-    {
-      seiChromaSamplingFilterHint->m_verTapLengthMinus1[i] = 0;
-      seiChromaSamplingFilterHint->m_verFilterCoeff[i] = (Int*)malloc(seiChromaSamplingFilterHint->m_verTapLengthMinus1[i] * sizeof(Int));
-      for(Int j = 0; j < seiChromaSamplingFilterHint->m_verTapLengthMinus1[i]; j ++)
-      {
-        seiChromaSamplingFilterHint->m_verFilterCoeff[i][j] = 0;
-      }
-    }
+template <typename T>
+static Void readTokenValue(T            &returnedValue, /// value returned
+                           Bool         &failed,        /// used and updated
+                           std::istream &is,            /// stream to read token from
+                           const TChar  *pToken)        /// token string
+{
+  returnedValue=T();
+  if (failed)
+  {
+    return;
+  }
+
+  Int c;
+  // Ignore any whitespace
+  while ((c=is.get())!=EOF && isspace(c));
+  // test for comment mark
+  while (c=='#')
+  {
+    // Ignore to the end of the line
+    while ((c=is.get())!=EOF && (c!=10 && c!=13));
+    // Ignore any white space at the start of the next line
+    while ((c=is.get())!=EOF && isspace(c));
+  }
+  // test first character of token
+  failed=(c!=pToken[0]);
+  // test remaining characters of token
+  Int pos;
+  for(pos=1;!failed && pToken[pos]!=0 && is.get()==pToken[pos]; pos++);
+  failed|=(pToken[pos]!=0);
+  // Ignore any whitespace before the ':'
+  while (!failed && (c=is.get())!=EOF && isspace(c));
+  failed|=(c!=':');
+  // Now read the value associated with the token:
+  if (!failed)
+  {
+    is >> returnedValue;
+    failed=!is.good();
+    if (!failed)
+    {
+      c=is.get();
+      failed=(c!=EOF && !isspace(c));
+    }
+  }
+  if (failed)
+  {
+    std::cerr << "Unable to read token '" << pToken << "'\n";
+  }
+}
+
+template <typename T>
+static Void readTokenValueAndValidate(T            &returnedValue, /// value returned
+                                      Bool         &failed,        /// used and updated
+                                      std::istream &is,            /// stream to read token from
+                                      const TChar  *pToken,        /// token string
+                                      const T      &minInclusive,  /// minimum value allowed, inclusive
+                                      const T      &maxInclusive)  /// maximum value allowed, inclusive
+{
+  readTokenValue(returnedValue, failed, is, pToken);
+  if (!failed)
+  {
+    if (returnedValue<minInclusive || returnedValue>maxInclusive)
+    {
+      failed=true;
+      std::cerr << "Value for token " << pToken << " must be in the range " << minInclusive << " to " << maxInclusive << " (inclusive); value read: " << returnedValue << std::endl;
+    }
+  }
+}
+
+// Bool version does not have maximum and minimum values.
+static Void readTokenValueAndValidate(Bool         &returnedValue, /// value returned
+                                      Bool         &failed,        /// used and updated
+                                      std::istream &is,            /// stream to read token from
+                                      const TChar  *pToken)        /// token string
+{
+  readTokenValue(returnedValue, failed, is, pToken);
+}
+
+Bool SEIEncoder::initSEIColourRemappingInfo(SEIColourRemappingInfo* seiColourRemappingInfo, Int currPOC) // returns true on success, false on failure.
+{
+  assert (m_isInitialized);
+  assert (seiColourRemappingInfo!=NULL);
+
+  // reading external Colour Remapping Information SEI message parameters from file
+  if( !m_pcCfg->getColourRemapInfoSEIFileRoot().empty())
+  {
+    Bool failed=false;
+
+    // building the CRI file name with poc num in prefix "_poc.txt"
+    std::string colourRemapSEIFileWithPoc(m_pcCfg->getColourRemapInfoSEIFileRoot());
+    {
+      std::stringstream suffix;
+      suffix << "_" << currPOC << ".txt";
+      colourRemapSEIFileWithPoc+=suffix.str();
+    }
+
+    std::ifstream fic(colourRemapSEIFileWithPoc.c_str());
+    if (!fic.good() || !fic.is_open())
+    {
+      std::cerr <<  "No Colour Remapping Information SEI parameters file " << colourRemapSEIFileWithPoc << " for POC " << currPOC << std::endl;
+      return false;
+    }
+
+    // TODO: identify and remove duplication with decoder parsing through abstraction.
+
+    readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapId,         failed, fic, "colour_remap_id",        UInt(0), UInt(0x7fffffff) );
+    readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapCancelFlag, failed, fic, "colour_remap_cancel_flag" );
+    if( !seiColourRemappingInfo->m_colourRemapCancelFlag )
+    {
+      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapPersistenceFlag,            failed, fic, "colour_remap_persistence_flag" );
+      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag, failed, fic, "colour_remap_video_signal_info_present_flag");
+      if( seiColourRemappingInfo->m_colourRemapVideoSignalInfoPresentFlag )
+      {
+        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapFullRangeFlag,      failed, fic, "colour_remap_full_range_flag" );
+        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapPrimaries,          failed, fic, "colour_remap_primaries",           Int(0), Int(255) );
+        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapTransferFunction,   failed, fic, "colour_remap_transfer_function",   Int(0), Int(255) );
+        readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapMatrixCoefficients, failed, fic, "colour_remap_matrix_coefficients", Int(0), Int(255) );
+      }
+      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapInputBitDepth, failed, fic, "colour_remap_input_bit_depth",            Int(8), Int(16) );
+      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapBitDepth,      failed, fic, "colour_remap_bit_depth",                  Int(8), Int(16) );
+
+      const Int maximumInputValue    = (1 << (((seiColourRemappingInfo->m_colourRemapInputBitDepth + 7) >> 3) << 3)) - 1;
+      const Int maximumRemappedValue = (1 << (((seiColourRemappingInfo->m_colourRemapBitDepth      + 7) >> 3) << 3)) - 1;
+
+      for( Int c=0 ; c<3 ; c++ )
+      {
+        readTokenValueAndValidate(seiColourRemappingInfo->m_preLutNumValMinus1[c],         failed, fic, "pre_lut_num_val_minus1[c]",        Int(0), Int(32) );
+        if( seiColourRemappingInfo->m_preLutNumValMinus1[c]>0 )
+        {
+          seiColourRemappingInfo->m_preLut[c].resize(seiColourRemappingInfo->m_preLutNumValMinus1[c]+1);
+          for( Int i=0 ; i<=seiColourRemappingInfo->m_preLutNumValMinus1[c] ; i++ )
+          {
+            readTokenValueAndValidate(seiColourRemappingInfo->m_preLut[c][i].codedValue,   failed, fic, "pre_lut_coded_value[c][i]",  Int(0), maximumInputValue    );
+            readTokenValueAndValidate(seiColourRemappingInfo->m_preLut[c][i].targetValue,  failed, fic, "pre_lut_target_value[c][i]", Int(0), maximumRemappedValue );
+          }
+        }
+      }
+      readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapMatrixPresentFlag, failed, fic, "colour_remap_matrix_present_flag" );
+      if( seiColourRemappingInfo->m_colourRemapMatrixPresentFlag )
+      {
+        readTokenValueAndValidate(seiColourRemappingInfo->m_log2MatrixDenom, failed, fic, "log2_matrix_denom", Int(0), Int(15) );
+        for( Int c=0 ; c<3 ; c++ )
+        {
+          for( Int i=0 ; i<3 ; i++ )
+          {
+            readTokenValueAndValidate(seiColourRemappingInfo->m_colourRemapCoeffs[c][i], failed, fic, "colour_remap_coeffs[c][i]", -32768, 32767 );
+          }
+        }
+      }
+      for( Int c=0 ; c<3 ; c++ )
+      {
+        readTokenValueAndValidate(seiColourRemappingInfo->m_postLutNumValMinus1[c], failed, fic, "post_lut_num_val_minus1[c]", Int(0), Int(32) );
+        if( seiColourRemappingInfo->m_postLutNumValMinus1[c]>0 )
+        {
+          seiColourRemappingInfo->m_postLut[c].resize(seiColourRemappingInfo->m_postLutNumValMinus1[c]+1);
+          for( Int i=0 ; i<=seiColourRemappingInfo->m_postLutNumValMinus1[c] ; i++ )
+          {
+            readTokenValueAndValidate(seiColourRemappingInfo->m_postLut[c][i].codedValue,  failed, fic, "post_lut_coded_value[c][i]",  Int(0), maximumRemappedValue );
+            readTokenValueAndValidate(seiColourRemappingInfo->m_postLut[c][i].targetValue, failed, fic, "post_lut_target_value[c][i]", Int(0), maximumRemappedValue );
+          }
+        }
+      }
+    }
+
+    if( failed )
+    {
+      std::cerr << "Error while reading Colour Remapping Information SEI parameters file '" << colourRemapSEIFileWithPoc << "'" << std::endl;
+      exit(EXIT_FAILURE);
+    }
+  }
+  return true;
+}
+
+
+Void SEIEncoder::initSEIChromaResamplingFilterHint(SEIChromaResamplingFilterHint *seiChromaResamplingFilterHint, Int iHorFilterIndex, Int iVerFilterIndex)
+{
+  assert (m_isInitialized);
+  assert (seiChromaResamplingFilterHint!=NULL);
+
+  seiChromaResamplingFilterHint->m_verChromaFilterIdc = iVerFilterIndex;
+  seiChromaResamplingFilterHint->m_horChromaFilterIdc = iHorFilterIndex;
+  seiChromaResamplingFilterHint->m_verFilteringFieldProcessingFlag = 1;
+  seiChromaResamplingFilterHint->m_targetFormatIdc = 3;
+  seiChromaResamplingFilterHint->m_perfectReconstructionFlag = false;
+
+  // this creates some example filter values, if explicit filter definition is selected
+  if (seiChromaResamplingFilterHint->m_verChromaFilterIdc == 1)
+    {
+    const Int numVerticalFilters = 3;
+    const Int verTapLengthMinus1[] = {5,3,3};
+
+    seiChromaResamplingFilterHint->m_verFilterCoeff.resize(numVerticalFilters);
+    for(Int i = 0; i < numVerticalFilters; i ++)
+      {
+      seiChromaResamplingFilterHint->m_verFilterCoeff[i].resize(verTapLengthMinus1[i]+1);
+    }
+    // Note: C++11 -> seiChromaResamplingFilterHint->m_verFilterCoeff[0] = {-3,13,31,23,3,-3};
+    seiChromaResamplingFilterHint->m_verFilterCoeff[0][0] = -3;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[0][1] = 13;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[0][2] = 31;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[0][3] = 23;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[0][4] = 3;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[0][5] = -3;
+
+    seiChromaResamplingFilterHint->m_verFilterCoeff[1][0] = -1;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[1][1] = 25;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[1][2] = 247;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[1][3] = -15;
+
+    seiChromaResamplingFilterHint->m_verFilterCoeff[2][0] = -20;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[2][1] = 186;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[2][2] = 100;
+    seiChromaResamplingFilterHint->m_verFilterCoeff[2][3] = -10;
   }
   else
   {
-    seiChromaSamplingFilterHint->m_numVerticalFilters = 0;
-    seiChromaSamplingFilterHint->m_verTapLengthMinus1 = NULL;
-    seiChromaSamplingFilterHint->m_verFilterCoeff = NULL;
-  }
-  if(seiChromaSamplingFilterHint->m_horChromaFilterIdc == 1)
-  {
-    seiChromaSamplingFilterHint->m_numHorizontalFilters = 1;
-    seiChromaSamplingFilterHint->m_horTapLengthMinus1 = (Int*)malloc(seiChromaSamplingFilterHint->m_numHorizontalFilters * sizeof(Int));
-    seiChromaSamplingFilterHint->m_horFilterCoeff = (Int**)malloc(seiChromaSamplingFilterHint->m_numHorizontalFilters * sizeof(Int*));
-    for(Int i = 0; i < seiChromaSamplingFilterHint->m_numHorizontalFilters; i ++)
-    {
-      seiChromaSamplingFilterHint->m_horTapLengthMinus1[i] = 0;
-      seiChromaSamplingFilterHint->m_horFilterCoeff[i] = (Int*)malloc(seiChromaSamplingFilterHint->m_horTapLengthMinus1[i] * sizeof(Int));
-      for(Int j = 0; j < seiChromaSamplingFilterHint->m_horTapLengthMinus1[i]; j ++)
-      {
-        seiChromaSamplingFilterHint->m_horFilterCoeff[i][j] = 0;
-      }
-    }
+    seiChromaResamplingFilterHint->m_verFilterCoeff.resize(0);
+  }
+
+  if (seiChromaResamplingFilterHint->m_horChromaFilterIdc == 1)
+    {
+    Int const numHorizontalFilters = 1;
+    const Int horTapLengthMinus1[] = {3};
+
+    seiChromaResamplingFilterHint->m_horFilterCoeff.resize(numHorizontalFilters);
+    for(Int i = 0; i < numHorizontalFilters; i ++)
+      {
+      seiChromaResamplingFilterHint->m_horFilterCoeff[i].resize(horTapLengthMinus1[i]+1);
+    }
+    seiChromaResamplingFilterHint->m_horFilterCoeff[0][0] = 1;
+    seiChromaResamplingFilterHint->m_horFilterCoeff[0][1] = 6;
+    seiChromaResamplingFilterHint->m_horFilterCoeff[0][2] = 1;
   }
   else
   {
-    seiChromaSamplingFilterHint->m_numHorizontalFilters = 0;
-    seiChromaSamplingFilterHint->m_horTapLengthMinus1 = NULL;
-    seiChromaSamplingFilterHint->m_horFilterCoeff = NULL;
+    seiChromaResamplingFilterHint->m_horFilterCoeff.resize(0);
   }
 }
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIEncoder.h	(revision 1360)
@@ -79,6 +79,7 @@
   Void initSEITempMotionConstrainedTileSets (SEITempMotionConstrainedTileSets *sei, const TComPPS *pps);
   Void initSEIKneeFunctionInfo(SEIKneeFunctionInfo *sei);
-  Void initSEIChromaSamplingFilterHint(SEIChromaSamplingFilterHint *sei, Int iHorFilterIndex, Int iVerFilterIndex);
+  Void initSEIChromaResamplingFilterHint(SEIChromaResamplingFilterHint *sei, Int iHorFilterIndex, Int iVerFilterIndex);
   Void initSEITimeCode(SEITimeCode *sei);
+  Bool initSEIColourRemappingInfo(SEIColourRemappingInfo *sei, Int currPOC); // returns true on success, false on failure.
 
   // trailing SEIs
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIwrite.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIwrite.cpp	(revision 1360)
@@ -106,6 +106,6 @@
     xWriteSEIScalableNesting(bs, *static_cast<const SEIScalableNesting*>(&sei), sps);
     break;
-  case SEI::CHROMA_SAMPLING_FILTER_HINT:
-    xWriteSEIChromaSamplingFilterHint(*static_cast<const SEIChromaSamplingFilterHint*>(&sei)/*, sps*/);
+  case SEI::CHROMA_RESAMPLING_FILTER_HINT:
+    xWriteSEIChromaResamplingFilterHint(*static_cast<const SEIChromaResamplingFilterHint*>(&sei));
     break;
   case SEI::TEMP_MOTION_CONSTRAINED_TILE_SETS:
@@ -117,4 +117,7 @@
   case SEI::KNEE_FUNCTION_INFO:
     xWriteSEIKneeFunctionInfo(*static_cast<const SEIKneeFunctionInfo*>(&sei));
+    break;
+  case SEI::COLOUR_REMAPPING_INFO:
+    xWriteSEIColourRemappingInfo(*static_cast<const SEIColourRemappingInfo*>(&sei));
     break;
   case SEI::MASTERING_DISPLAY_COLOUR_VOLUME:
@@ -189,5 +192,5 @@
 
   default:
-    assert(!"Unhandled SEI message");
+    assert(!"Trying to write unhandled SEI message");
     break;
   }
@@ -277,10 +280,10 @@
 Void SEIWriter::xWriteSEIDecodedPictureHash(const SEIDecodedPictureHash& sei)
 {
-  const Char *traceString="\0";
+  const TChar *traceString="\0";
   switch (sei.method)
   {
-    case SEIDecodedPictureHash::MD5: traceString="picture_md5"; break;
-    case SEIDecodedPictureHash::CRC: traceString="picture_crc"; break;
-    case SEIDecodedPictureHash::CHECKSUM: traceString="picture_checksum"; break;
+    case HASHTYPE_MD5: traceString="picture_md5"; break;
+    case HASHTYPE_CRC: traceString="picture_crc"; break;
+    case HASHTYPE_CHECKSUM: traceString="picture_checksum"; break;
     default: assert(false); break;
   }
@@ -726,86 +729,48 @@
 }
 
-Void SEIWriter::xWriteSEIChromaSamplingFilterHint(const SEIChromaSamplingFilterHint &sei/*, TComSPS* sps*/)
+Void SEIWriter::xWriteSEIChromaResamplingFilterHint(const SEIChromaResamplingFilterHint &sei)
 {
   WRITE_CODE(sei.m_verChromaFilterIdc, 8, "ver_chroma_filter_idc");
   WRITE_CODE(sei.m_horChromaFilterIdc, 8, "hor_chroma_filter_idc");
-  WRITE_FLAG(sei.m_verFilteringProcessFlag, "ver_filtering_process_flag");
+  WRITE_FLAG(sei.m_verFilteringFieldProcessingFlag, "ver_filtering_field_processing_flag");
   if(sei.m_verChromaFilterIdc == 1 || sei.m_horChromaFilterIdc == 1)
   {
-    writeUserDefinedCoefficients(sei);
-  }
-}
-
-// write hardcoded chroma filter coefficients in the SEI messages
-Void SEIWriter::writeUserDefinedCoefficients(const SEIChromaSamplingFilterHint &sei)
-{
-  Int const iNumVerticalFilters = 3;
-  Int verticalTapLength_minus1[iNumVerticalFilters] = {5,3,3};
-  Int* userVerticalCoefficients[iNumVerticalFilters];
-  for(Int i = 0; i < iNumVerticalFilters; i ++)
-  {
-    userVerticalCoefficients[i] = (Int*)malloc( (verticalTapLength_minus1[i]+1) * sizeof(Int));
-  }
-  userVerticalCoefficients[0][0] = -3;
-  userVerticalCoefficients[0][1] = 13;
-  userVerticalCoefficients[0][2] = 31;
-  userVerticalCoefficients[0][3] = 23;
-  userVerticalCoefficients[0][4] = 3;
-  userVerticalCoefficients[0][5] = -3;
-
-  userVerticalCoefficients[1][0] = -1;
-  userVerticalCoefficients[1][1] = 25;
-  userVerticalCoefficients[1][2] = 247;
-  userVerticalCoefficients[1][3] = -15;
-
-  userVerticalCoefficients[2][0] = -20;
-  userVerticalCoefficients[2][1] = 186;
-  userVerticalCoefficients[2][2] = 100;
-  userVerticalCoefficients[2][3] = -10;
-
-  Int const iNumHorizontalFilters = 1;
-  Int horizontalTapLength_minus1[iNumHorizontalFilters] = {3};
-  Int* userHorizontalCoefficients[iNumHorizontalFilters];
-  for(Int i = 0; i < iNumHorizontalFilters; i ++)
-  {
-    userHorizontalCoefficients[i] = (Int*)malloc( (horizontalTapLength_minus1[i]+1) * sizeof(Int));
-  }
-  userHorizontalCoefficients[0][0] = 1;
-  userHorizontalCoefficients[0][1] = 6;
-  userHorizontalCoefficients[0][2] = 1;
-
-  WRITE_UVLC(3, "target_format_idc");
-  if(sei.m_verChromaFilterIdc == 1)
-  {
-    WRITE_UVLC(iNumVerticalFilters, "num_vertical_filters");
-    if(iNumVerticalFilters > 0)
-    {
-      for(Int i = 0; i < iNumVerticalFilters; i ++)
-      {
-        WRITE_UVLC(verticalTapLength_minus1[i], "ver_tap_length_minus_1");
-        for(Int j = 0; j < verticalTapLength_minus1[i]; j ++)
-        {
-          WRITE_SVLC(userVerticalCoefficients[i][j], "ver_filter_coeff");
-        }
-      }
-    }
-  }
-  if(sei.m_horChromaFilterIdc == 1)
-  {
-    WRITE_UVLC(iNumHorizontalFilters, "num_horizontal_filters");
-    if(iNumHorizontalFilters > 0)
-    {
-      for(Int i = 0; i < iNumHorizontalFilters; i ++)
-      {
-        WRITE_UVLC(horizontalTapLength_minus1[i], "hor_tap_length_minus_1");
-        for(Int j = 0; j < horizontalTapLength_minus1[i]; j ++)
-        {
-          WRITE_SVLC(userHorizontalCoefficients[i][j], "hor_filter_coeff");
-        }
-      }
-    }
-  }
-}
-
+    WRITE_UVLC(sei.m_targetFormatIdc, "target_format_idc");
+    if(sei.m_verChromaFilterIdc == 1)
+    {
+      const Int numVerticalFilter = (Int)sei.m_verFilterCoeff.size();
+      WRITE_UVLC(numVerticalFilter, "num_vertical_filters");
+      if(numVerticalFilter > 0)
+      {
+        for(Int i = 0; i < numVerticalFilter; i ++)
+        {
+          const Int verTapLengthMinus1 = (Int) sei.m_verFilterCoeff[i].size() - 1;
+          WRITE_UVLC(verTapLengthMinus1, "ver_tap_length_minus_1");
+          for(Int j = 0; j < (verTapLengthMinus1 + 1); j ++)
+          {
+            WRITE_SVLC(sei.m_verFilterCoeff[i][j], "ver_filter_coeff");
+          }
+        }
+      }
+    }
+    if(sei.m_horChromaFilterIdc == 1)
+    {
+      const Int numHorizontalFilter = (Int) sei.m_horFilterCoeff.size();
+      WRITE_UVLC(numHorizontalFilter, "num_horizontal_filters");
+      if(numHorizontalFilter > 0)
+      {
+        for(Int i = 0; i < numHorizontalFilter; i ++)
+        {
+          const Int horTapLengthMinus1 = (Int) sei.m_horFilterCoeff[i].size() - 1;
+          WRITE_UVLC(horTapLengthMinus1, "hor_tap_length_minus_1");
+          for(Int j = 0; j < (horTapLengthMinus1 + 1); j ++)
+          {
+            WRITE_SVLC(sei.m_horFilterCoeff[i][j], "hor_filter_coeff");
+          }
+        }
+      }
+    }
+  }
+}
 #if NH_MV
 #if !NH_MV_SEI
@@ -849,4 +814,60 @@
 }
 
+Void SEIWriter::xWriteSEIColourRemappingInfo(const SEIColourRemappingInfo& sei)
+{
+  WRITE_UVLC( sei.m_colourRemapId,                             "colour_remap_id" );
+  WRITE_FLAG( sei.m_colourRemapCancelFlag,                     "colour_remap_cancel_flag" );
+  if( !sei.m_colourRemapCancelFlag ) 
+  {
+    WRITE_FLAG( sei.m_colourRemapPersistenceFlag,              "colour_remap_persistence_flag" );
+    WRITE_FLAG( sei.m_colourRemapVideoSignalInfoPresentFlag,   "colour_remap_video_signal_info_present_flag" );
+    if ( sei.m_colourRemapVideoSignalInfoPresentFlag )
+    {
+      WRITE_FLAG( sei.m_colourRemapFullRangeFlag,              "colour_remap_full_range_flag" );
+      WRITE_CODE( sei.m_colourRemapPrimaries,               8, "colour_remap_primaries" );
+      WRITE_CODE( sei.m_colourRemapTransferFunction,        8, "colour_remap_transfer_function" );
+      WRITE_CODE( sei.m_colourRemapMatrixCoefficients,      8, "colour_remap_matrix_coefficients" );
+    }
+    WRITE_CODE( sei.m_colourRemapInputBitDepth,             8, "colour_remap_input_bit_depth" );
+    WRITE_CODE( sei.m_colourRemapBitDepth,                  8, "colour_remap_bit_depth" );
+    for( Int c=0 ; c<3 ; c++ )
+    {
+      WRITE_CODE( sei.m_preLutNumValMinus1[c],              8, "pre_lut_num_val_minus1[c]" );
+      if( sei.m_preLutNumValMinus1[c]>0 )
+      {
+        for( Int i=0 ; i<=sei.m_preLutNumValMinus1[c] ; i++ )
+        {
+          WRITE_CODE( sei.m_preLut[c][i].codedValue,  (( sei.m_colourRemapInputBitDepth + 7 ) >> 3 ) << 3, "pre_lut_coded_value[c][i]" );
+          WRITE_CODE( sei.m_preLut[c][i].targetValue, (( sei.m_colourRemapBitDepth      + 7 ) >> 3 ) << 3, "pre_lut_target_value[c][i]" );
+        }
+      }
+    }
+    WRITE_FLAG( sei.m_colourRemapMatrixPresentFlag,            "colour_remap_matrix_present_flag" );
+    if( sei.m_colourRemapMatrixPresentFlag )
+    {
+      WRITE_CODE( sei.m_log2MatrixDenom,                    4, "log2_matrix_denom" );
+      for( Int c=0 ; c<3 ; c++ )
+      {
+        for( Int i=0 ; i<3 ; i++ )
+        {
+          WRITE_SVLC( sei.m_colourRemapCoeffs[c][i],           "colour_remap_coeffs[c][i]" );
+        }
+      }
+    }
+
+    for( Int c=0 ; c<3 ; c++ )
+    {
+      WRITE_CODE( sei.m_postLutNumValMinus1[c],             8, "m_postLutNumValMinus1[c]" );
+      if( sei.m_postLutNumValMinus1[c]>0 )
+      {
+        for( Int i=0 ; i<=sei.m_postLutNumValMinus1[c] ; i++ )
+        {
+          WRITE_CODE( sei.m_postLut[c][i].codedValue, (( sei.m_colourRemapBitDepth + 7 ) >> 3 ) << 3, "post_lut_coded_value[c][i]" );
+          WRITE_CODE( sei.m_postLut[c][i].targetValue, (( sei.m_colourRemapBitDepth + 7 ) >> 3 ) << 3, "post_lut_target_value[c][i]" );
+        }
+      }
+    }
+  }
+}
 
 Void SEIWriter::xWriteSEIMasteringDisplayColourVolume(const SEIMasteringDisplayColourVolume& sei)
@@ -863,5 +884,5 @@
   WRITE_CODE( sei.values.whitePoint[0],    16,  "white_point_x" );
   WRITE_CODE( sei.values.whitePoint[1],    16,  "white_point_y" );
-
+    
   WRITE_CODE( sei.values.maxLuminance,     32,  "max_display_mastering_luminance" );
   WRITE_CODE( sei.values.minLuminance,     32,  "min_display_mastering_luminance" );
@@ -881,4 +902,5 @@
 }
 
+
 #if NH_MV_LAYERS_NOT_PRESENT_SEI
 Void SEIWriter::xWriteSEILayersNotPresent(const SEILayersNotPresent& sei)
@@ -892,6 +914,5 @@
 #endif
 
-
-
+#if NH_MV
 Void SEIWriter::xWriteSEIInterLayerConstrainedTileSets( const SEIInterLayerConstrainedTileSets& sei)
 {
@@ -927,4 +948,5 @@
   }
 };
+#endif
 
 #if NH_MV_SEI_TBD
@@ -1067,4 +1089,5 @@
   }
 };
+
 
 Void SEIWriter::xWriteSEITemporalMvPredictionConstraints( const SEITemporalMvPredictionConstraints& sei)
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIwrite.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/SEIwrite.h	(revision 1360)
@@ -53,5 +53,4 @@
 
 protected:
-  Void xWriteSEIpayloadData(TComBitIf& bs, const SEI& sei, const TComSPS *sps);
   Void xWriteSEIuserDataUnregistered(const SEIuserDataUnregistered &sei);
   Void xWriteSEIActiveParameterSets(const SEIActiveParameterSets& sei);
@@ -60,5 +59,4 @@
   Void xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const TComSPS *sps);
   Void xWriteSEIPictureTiming(const SEIPictureTiming& sei, const TComSPS *sps);
-  TComSPS *m_pSPS;
   Void xWriteSEIRecoveryPoint(const SEIRecoveryPoint& sei);
   Void xWriteSEIFramePacking(const SEIFramePacking& sei);
@@ -78,7 +76,7 @@
   Void xWriteSEITempMotionConstrainedTileSets(const SEITempMotionConstrainedTileSets& sei);
   Void xWriteSEITimeCode(const SEITimeCode& sei);
-  Void xWriteSEIChromaSamplingFilterHint(const SEIChromaSamplingFilterHint& sei/*, TComSPS *sps*/);
-  Void writeUserDefinedCoefficients(const SEIChromaSamplingFilterHint& sei);
+  Void xWriteSEIChromaResamplingFilterHint(const SEIChromaResamplingFilterHint& sei);
   Void xWriteSEIKneeFunctionInfo(const SEIKneeFunctionInfo &sei);
+  Void xWriteSEIColourRemappingInfo(const SEIColourRemappingInfo& sei);
   Void xWriteSEIMasteringDisplayColourVolume( const SEIMasteringDisplayColourVolume& sei);
 
@@ -110,4 +108,5 @@
   Void xWriteSEIAlternativeDepthInfo          ( const SEIAlternativeDepthInfo& sei);
 #endif
+  Void xWriteSEIpayloadData(TComBitIf& bs, const SEI& sei, const TComSPS *sps);
   Void xWriteByteAlign();
 };
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/SyntaxElementWriter.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/SyntaxElementWriter.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/SyntaxElementWriter.cpp	(revision 1360)
@@ -44,5 +44,5 @@
 #if ENC_DEC_TRACE
 
-Void  SyntaxElementWriter::xWriteCodeTr (UInt value, UInt  length, const Char *pSymbolName)
+Void  SyntaxElementWriter::xWriteCodeTr (UInt value, UInt  length, const TChar *pSymbolName)
 {
   xWriteCode (value,length);
@@ -70,5 +70,5 @@
 }
 
-Void  SyntaxElementWriter::xWriteUvlcTr (UInt value, const Char *pSymbolName)
+Void  SyntaxElementWriter::xWriteUvlcTr (UInt value, const TChar *pSymbolName)
 {
   xWriteUvlc (value);
@@ -89,5 +89,5 @@
 }
 
-Void  SyntaxElementWriter::xWriteSvlcTr (Int value, const Char *pSymbolName)
+Void  SyntaxElementWriter::xWriteSvlcTr (Int value, const TChar *pSymbolName)
 {
   xWriteSvlc(value);
@@ -108,5 +108,5 @@
 }
 
-Void  SyntaxElementWriter::xWriteFlagTr(UInt value, const Char *pSymbolName)
+Void  SyntaxElementWriter::xWriteFlagTr(UInt value, const TChar *pSymbolName)
 {
   xWriteFlag(value);
@@ -127,4 +127,5 @@
 }
 
+#if H_MV_ENC_DEC_TRAC
 Void  SyntaxElementWriter::xWriteStringTr( UChar* value, UInt length, const Char *pSymbolName)
 {
@@ -136,5 +137,5 @@
   }
 }
-
+#endif
 #endif
 
@@ -176,4 +177,5 @@
 }
 
+#if H_MV_ENC_DEC_TRAC
 Void  SyntaxElementWriter::xWriteString( UChar* sCode, UInt uiLength)
 {
@@ -185,5 +187,5 @@
   m_pcBitIf->write( 0, 8 ); //zero-termination byte
 }
-
+#endif
 Void SyntaxElementWriter::xWriteRbspTrailingBits()
 {
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/SyntaxElementWriter.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/SyntaxElementWriter.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/SyntaxElementWriter.h	(revision 1360)
@@ -56,5 +56,7 @@
 #define WRITE_SVLC( value,         name)    xWriteSvlcTr ( value,         name )
 #define WRITE_FLAG( value,         name)    xWriteFlagTr ( value,         name )
+#if NH_MV
 #define WRITE_STRING( value, length, name)   xWriteStringTr( value, length, name )
+#endif
 
 #else
@@ -64,6 +66,7 @@
 #define WRITE_SVLC( value,         name)     xWriteSvlc ( value )
 #define WRITE_FLAG( value,         name)     xWriteFlag ( value )
+#if NH_MV
 #define WRITE_STRING( value, length, name)   xWriteString( value, length )
-
+#endif
 #endif
 
@@ -84,11 +87,15 @@
   Void  xWriteSvlc            ( Int  iCode   );
   Void  xWriteFlag            ( UInt uiCode );
+#if NH_MV
   Void  xWriteString          ( UChar* sCode, UInt uiLength);
+#endif
 #if ENC_DEC_TRACE
-  Void  xWriteCodeTr          ( UInt value, UInt  length, const Char *pSymbolName);
-  Void  xWriteUvlcTr          ( UInt value,               const Char *pSymbolName);
-  Void  xWriteSvlcTr          ( Int  value,               const Char *pSymbolName);
-  Void  xWriteFlagTr          ( UInt value,               const Char *pSymbolName);
+  Void  xWriteCodeTr          ( UInt value, UInt  length, const TChar *pSymbolName);
+  Void  xWriteUvlcTr          ( UInt value,               const TChar *pSymbolName);
+  Void  xWriteSvlcTr          ( Int  value,               const TChar *pSymbolName);
+  Void  xWriteFlagTr          ( UInt value,               const TChar *pSymbolName);
+#if NH_MV
   Void  xWriteStringTr        ( UChar* value, UInt length, const Char *pSymbolName);
+#endif
 #endif
   Void xWriteRbspTrailingBits();
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncAnalyze.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncAnalyze.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncAnalyze.h	(revision 1360)
@@ -137,5 +137,5 @@
 
 
-  Void    printOut ( Char cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths )
+  Void    printOut ( TChar cDelim, const ChromaFormat chFmt, const Bool printMSEBasedSNR, const Bool printSequenceMSE, const BitDepths &bitDepths )
   {
     Double dFps     =   m_dFrmRate; //--CFG_KDY
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncBinCoderCABAC.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncBinCoderCABAC.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncBinCoderCABAC.cpp	(revision 1360)
@@ -246,5 +246,5 @@
   if (g_debugCounter >= debugCabacBinTargetLine)
   {
-    Char breakPointThis;
+    UChar breakPointThis;
     breakPointThis = 7;
   }
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncBinCoderCABACCounter.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncBinCoderCABACCounter.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncBinCoderCABACCounter.cpp	(revision 1360)
@@ -97,5 +97,5 @@
   if (g_debugCounter >= debugEncoderSearchBinTargetLine)
   {
-    Char breakPointThis;
+    UChar breakPointThis;
     breakPointThis = 7;
   }
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 1360)
@@ -69,6 +69,25 @@
   fprintf( g_hTrace, "=========== Slice ===========\n");
 }
-#endif
-#endif
+
+Void  xTraceAccessUnitDelimiter ()
+{
+  fprintf( g_hTrace, "=========== Access Unit Delimiter ===========\n");
+}
+
+#endif
+#endif
+
+Void AUDWriter::codeAUD(TComBitIf& bs, const Int pictureType)
+{
+#if ENC_DEC_TRACE
+  xTraceAccessUnitDelimiter();
+#endif
+
+  assert (pictureType < 3);
+  setBitstream(&bs);
+  WRITE_CODE(pictureType, 3, "pic_type");
+  xWriteRbspTrailingBits();
+}
+
 // ====================================================================================================================
 // Constructor / destructor / create / destroy
@@ -266,5 +285,5 @@
   {
 #if ENC_DEC_TRACE || RExt__DECODER_DEBUG_BIT_STATISTICS
-    static const char *syntaxStrings[]={ "pps_range_extension_flag",
+    static const TChar *syntaxStrings[]={ "pps_range_extension_flag",
                                          "pps_multilayer_extension_flag",
                                          "pps_extension_6bits[0]",
@@ -748,5 +767,5 @@
     WRITE_UVLC( pcSPS->getSpsMaxLatencyIncreasePlus1(i),   "sps_max_latency_increase_plus1[i]" );
 #else
-    WRITE_UVLC( pcSPS->getMaxLatencyIncrease(i),           "sps_max_latency_increase_plus1[i]" );
+    WRITE_UVLC( pcSPS->getMaxLatencyIncreasePlus1(i),      "sps_max_latency_increase_plus1[i]" );
 #endif
     if (!subLayerOrderingInfoPresentFlag)
@@ -858,5 +877,5 @@
   {
 #if ENC_DEC_TRACE || RExt__DECODER_DEBUG_BIT_STATISTICS
-    static const char *syntaxStrings[]={ "sps_range_extension_flag",
+    static const TChar *syntaxStrings[]={ "sps_range_extension_flag",
       "sps_multilayer_extension_flag",
       "sps_extension_6bits[0]",
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCavlc.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCavlc.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCavlc.h	(revision 1360)
@@ -58,4 +58,13 @@
 // ====================================================================================================================
 
+class AUDWriter : public SyntaxElementWriter
+{
+public:
+  AUDWriter() {};
+  virtual ~AUDWriter() {};
+
+  Void  codeAUD(TComBitIf& bs, const Int pictureType);
+};
+
 /// CAVLC encoder class
 class TEncCavlc : public SyntaxElementWriter, public TEncEntropyIf
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1360)
@@ -65,5 +65,5 @@
   Bool m_refPic;
   Int m_numRefPicsActive;
-  Char m_sliceType;
+  SChar m_sliceType;
   Int m_numRefPics;
   Int m_referencePics[MAX_NUM_REF_PICS];
@@ -137,4 +137,6 @@
   Int       m_framesToBeEncoded;
   Double    m_adLambdaModifier[ MAX_TLAYER ];
+  std::vector<Double> m_adIntraLambdaModifier;
+  Double    m_dIntraQpFactor;                                 ///< Intra Q Factor. If negative, use a default equation: 0.57*(1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? (GopSize-1)/2 : GopSize-1) ))
 
   Bool      m_printMSEBasedSequencePSNR;
@@ -174,4 +176,5 @@
   Int       m_aiPad[2];
 
+  Bool      m_AccessUnitDelimiter;               ///< add Access Unit Delimiter NAL units
 
   Int       m_iMaxRefPicNum;                     ///< this is used to mimic the sliding mechanism used by the decoder
@@ -206,9 +209,11 @@
   //====== Motion search ========
   Bool      m_bDisableIntraPUsInInterSlices;
-  Int       m_iFastSearch;                      //  0:Full search  1:Diamond  2:PMVFAST
+  MESearchMethod m_motionEstimationSearchMethod;
   Int       m_iSearchRange;                     //  0:Full frame
   Int       m_bipredSearchRange;
   Bool      m_bClipForBiPredMeEnabled;
   Bool      m_bFastMEAssumingSmootherMVEnabled;
+  Int       m_minSearchWindow;
+  Bool      m_bRestrictMESampling;
 
 #if NH_MV
@@ -243,5 +248,5 @@
 #endif
   UInt      m_rdPenalty;
-  Bool      m_bUseFastEnc;
+  FastInterSearchMode m_fastInterSearchMode;
   Bool      m_bUseEarlyCU;
   Bool      m_useFastDecisionForMerge;
@@ -289,10 +294,10 @@
   std::vector<Int> m_tileRowHeight;
 
-  Int       m_iWaveFrontSynchro;
-
-  Int       m_decodedPictureHashSEIEnabled;              ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
-  Int       m_bufferingPeriodSEIEnabled;
-  Int       m_pictureTimingSEIEnabled;
-  Int       m_recoveryPointSEIEnabled;
+  Bool      m_entropyCodingSyncEnabledFlag;
+
+  HashType  m_decodedPictureHashSEIType;
+  Bool      m_bufferingPeriodSEIEnabled;
+  Bool      m_pictureTimingSEIEnabled;
+  Bool      m_recoveryPointSEIEnabled;
   Bool      m_toneMappingInfoSEIEnabled;
   Int       m_toneMapId;
@@ -322,20 +327,20 @@
   Int*      m_codedPivotValue;
   Int*      m_targetPivotValue;
-  Int       m_framePackingSEIEnabled;
+  Bool      m_framePackingSEIEnabled;
   Int       m_framePackingSEIType;
   Int       m_framePackingSEIId;
   Int       m_framePackingSEIQuincunx;
   Int       m_framePackingSEIInterpretation;
-  Int       m_segmentedRectFramePackingSEIEnabled;
+  Bool      m_segmentedRectFramePackingSEIEnabled;
   Bool      m_segmentedRectFramePackingSEICancel;
   Int       m_segmentedRectFramePackingSEIType;
   Bool      m_segmentedRectFramePackingSEIPersistence;
   Int       m_displayOrientationSEIAngle;
-  Int       m_temporalLevel0IndexSEIEnabled;
-  Int       m_gradualDecodingRefreshInfoEnabled;
+  Bool      m_temporalLevel0IndexSEIEnabled;
+  Bool      m_gradualDecodingRefreshInfoEnabled;
   Int       m_noDisplaySEITLayer;
-  Int       m_decodingUnitInfoSEIEnabled;
-  Int       m_SOPDescriptionSEIEnabled;
-  Int       m_scalableNestingSEIEnabled;
+  Bool      m_decodingUnitInfoSEIEnabled;
+  Bool      m_SOPDescriptionSEIEnabled;
+  Bool      m_scalableNestingSEIEnabled;
   Bool      m_tmctsSEIEnabled;
   Bool      m_timeCodeSEIEnabled;
@@ -353,4 +358,5 @@
   Int*      m_kneeSEIInputKneePoint;
   Int*      m_kneeSEIOutputKneePoint;
+  std::string m_colourRemapSEIFileRoot;          ///< SEI Colour Remapping File (initialized from external file)
   TComSEIMasteringDisplay m_masteringDisplay;
 #if NH_MV_SEI
@@ -360,8 +366,9 @@
   Bool      m_useWeightedPred;       //< Use of Weighting Prediction (P_SLICE)
   Bool      m_useWeightedBiPred;    //< Use of Bi-directional Weighting Prediction (B_SLICE)
+  WeightedPredictionMethod m_weightedPredictionMethod;
   UInt      m_log2ParallelMergeLevelMinus2;       ///< Parallel merge estimation region
   UInt      m_maxNumMergeCand;                    ///< Maximum number of merge candidates
   ScalingListMode m_useScalingListId;            ///< Using quantization matrix i.e. 0=off, 1=default, 2=file.
-  Char*     m_scalingListFile;          ///< quantization matrix file name
+  std::string m_scalingListFileName;              ///< quantization matrix file name
   Int       m_TMVPModeId;
   Bool      m_signHideFlag;
@@ -373,4 +380,9 @@
   Int       m_RCInitialQP;
   Bool      m_RCForceIntraQP;
+#if U0132_TARGET_BITS_SATURATION
+  Bool      m_RCCpbSaturationEnabled;                   
+  UInt      m_RCCpbSize;
+  Double    m_RCInitialCpbFullness;
+#endif
 
 #if KWU_RC_MADPRED_E0227
@@ -398,7 +410,7 @@
   Bool      m_vuiParametersPresentFlag;                       ///< enable generation of VUI parameters
   Bool      m_aspectRatioInfoPresentFlag;                     ///< Signals whether aspect_ratio_idc is present
-  Bool      m_chromaSamplingFilterHintEnabled;                ///< Signals whether chroma sampling filter hint data is present
-  Int       m_chromaSamplingHorFilterIdc;                     ///< Specifies the Index of filter to use
-  Int       m_chromaSamplingVerFilterIdc;                     ///< Specifies the Index of filter to use
+  Bool      m_chromaResamplingFilterHintEnabled;              ///< Signals whether chroma sampling filter hint data is present
+  Int       m_chromaResamplingHorFilterIdc;                   ///< Specifies the Index of filter to use
+  Int       m_chromaResamplingVerFilterIdc;                   ///< Specifies the Index of filter to use
   Int       m_aspectRatioIdc;                                 ///< aspect_ratio_idc
   Int       m_sarWidth;                                       ///< horizontal size of the sample aspect ratio
@@ -606,9 +618,12 @@
   //====== Motion search ========
   Void      setDisableIntraPUsInInterSlices ( Bool  b )      { m_bDisableIntraPUsInInterSlices = b; }
-  Void      setFastSearch                   ( Int   i )      { m_iFastSearch = i; }
+  Void      setMotionEstimationSearchMethod ( MESearchMethod e ) { m_motionEstimationSearchMethod = e; }
   Void      setSearchRange                  ( Int   i )      { m_iSearchRange = i; }
   Void      setBipredSearchRange            ( Int   i )      { m_bipredSearchRange = i; }
   Void      setClipForBiPredMeEnabled       ( Bool  b )      { m_bClipForBiPredMeEnabled = b; }
   Void      setFastMEAssumingSmootherMVEnabled ( Bool b )    { m_bFastMEAssumingSmootherMVEnabled = b; }
+  Void      setMinSearchWindow              ( Int   i )      { m_minSearchWindow = i; }
+  Void      setRestrictMESampling           ( Bool  b )      { m_bRestrictMESampling = b; }
+
 #if NH_MV
   Void      setUseDisparitySearchRangeRestriction ( Bool   b )      { m_bUseDisparitySearchRangeRestriction = b; }
@@ -649,6 +664,12 @@
   Int       getSourceHeight                 ()      { return  m_iSourceHeight; }
   Int       getFramesToBeEncoded            ()      { return  m_framesToBeEncoded; }
+  
+  //====== Lambda Modifiers ========
   Void setLambdaModifier                    ( UInt uiIndex, Double dValue ) { m_adLambdaModifier[ uiIndex ] = dValue; }
   Double getLambdaModifier                  ( UInt uiIndex ) const { return m_adLambdaModifier[ uiIndex ]; }
+  Void      setIntraLambdaModifier          ( const std::vector<Double> &dValue )               { m_adIntraLambdaModifier = dValue;       }
+  const std::vector<Double>& getIntraLambdaModifier()                        const { return m_adIntraLambdaModifier;         }
+  Void      setIntraQpFactor                ( Double dValue )               { m_dIntraQpFactor = dValue;              }
+  Double    getIntraQpFactor                ()                        const { return m_dIntraQpFactor;                }
 
   //==== Coding Structure ========
@@ -662,4 +683,7 @@
   Int       getPad                          ( Int i )      { assert (i < 2 );                      return  m_aiPad[i]; }
 
+  Bool      getAccessUnitDelimiter() const  { return m_AccessUnitDelimiter; }
+  Void      setAccessUnitDelimiter(Bool val){ m_AccessUnitDelimiter = val; }
+
   //======== Transform =============
   UInt      getQuadtreeTULog2MaxSize        ()      const { return m_uiQuadtreeTULog2MaxSize; }
@@ -677,8 +701,11 @@
   //==== Motion search ========
   Bool      getDisableIntraPUsInInterSlices () const { return m_bDisableIntraPUsInInterSlices; }
-  Int       getFastSearch                   () const { return m_iFastSearch; }
+  MESearchMethod getMotionEstimationSearchMethod ( ) const { return m_motionEstimationSearchMethod; }
   Int       getSearchRange                  () const { return m_iSearchRange; }
   Bool      getClipForBiPredMeEnabled       () const { return m_bClipForBiPredMeEnabled; }
   Bool      getFastMEAssumingSmootherMVEnabled ( ) const { return m_bFastMEAssumingSmootherMVEnabled; }
+  Int       getMinSearchWindow                 () const { return m_minSearchWindow; }
+  Bool      getRestrictMESampling              () const { return m_bRestrictMESampling; }
+
 #if NH_MV
   Bool      getUseDisparitySearchRangeRestriction ()      { return  m_bUseDisparitySearchRangeRestriction; }
@@ -701,6 +728,6 @@
   Void      setUseSelectiveRDOQ             ( Bool b )      { m_useSelectiveRDOQ = b; }
 #endif
-  Void      setRDpenalty                 ( UInt  b )     { m_rdPenalty  = b; }
-  Void      setUseFastEnc                   ( Bool  b )     { m_bUseFastEnc = b; }
+  Void      setRDpenalty                    ( UInt  u )     { m_rdPenalty  = u; }
+  Void      setFastInterSearchMode          ( FastInterSearchMode m ) { m_fastInterSearchMode = m; }
   Void      setUseEarlyCU                   ( Bool  b )     { m_bUseEarlyCU = b; }
   Void      setUseFastDecisionForMerge      ( Bool  b )     { m_useFastDecisionForMerge = b; }
@@ -729,5 +756,5 @@
 #endif
   Int       getRDpenalty                    ()      { return m_rdPenalty;  }
-  Bool      getUseFastEnc                   ()      { return m_bUseFastEnc; }
+  FastInterSearchMode getFastInterSearchMode() const{ return m_fastInterSearchMode;  }
   Bool      getUseEarlyCU                   ()      { return m_bUseEarlyCU; }
   Bool      getUseFastDecisionForMerge      ()      { return m_useFastDecisionForMerge; }
@@ -812,14 +839,14 @@
   UInt  getRowHeight                   ( UInt rowIdx )               { return m_tileRowHeight[rowIdx]; }
   Void  xCheckGSParameters();
-  Void  setWaveFrontSynchro(Int iWaveFrontSynchro)                   { m_iWaveFrontSynchro = iWaveFrontSynchro; }
-  Int   getWaveFrontsynchro()                                        { return m_iWaveFrontSynchro; }
-  Void  setDecodedPictureHashSEIEnabled(Int b)                       { m_decodedPictureHashSEIEnabled = b; }
-  Int   getDecodedPictureHashSEIEnabled()                            { return m_decodedPictureHashSEIEnabled; }
-  Void  setBufferingPeriodSEIEnabled(Int b)                          { m_bufferingPeriodSEIEnabled = b; }
-  Int   getBufferingPeriodSEIEnabled()                               { return m_bufferingPeriodSEIEnabled; }
-  Void  setPictureTimingSEIEnabled(Int b)                            { m_pictureTimingSEIEnabled = b; }
-  Int   getPictureTimingSEIEnabled()                                 { return m_pictureTimingSEIEnabled; }
-  Void  setRecoveryPointSEIEnabled(Int b)                            { m_recoveryPointSEIEnabled = b; }
-  Int   getRecoveryPointSEIEnabled()                                 { return m_recoveryPointSEIEnabled; }
+  Void  setEntropyCodingSyncEnabledFlag(Bool b)                      { m_entropyCodingSyncEnabledFlag = b; }
+  Bool  getEntropyCodingSyncEnabledFlag() const                      { return m_entropyCodingSyncEnabledFlag; }
+  Void  setDecodedPictureHashSEIType(HashType m)                     { m_decodedPictureHashSEIType = m; }
+  HashType getDecodedPictureHashSEIType() const                      { return m_decodedPictureHashSEIType; }
+  Void  setBufferingPeriodSEIEnabled(Bool b)                         { m_bufferingPeriodSEIEnabled = b; }
+  Bool  getBufferingPeriodSEIEnabled() const                         { return m_bufferingPeriodSEIEnabled; }
+  Void  setPictureTimingSEIEnabled(Bool b)                           { m_pictureTimingSEIEnabled = b; }
+  Bool  getPictureTimingSEIEnabled() const                           { return m_pictureTimingSEIEnabled; }
+  Void  setRecoveryPointSEIEnabled(Bool b)                           { m_recoveryPointSEIEnabled = b; }
+  Bool  getRecoveryPointSEIEnabled() const                           { return m_recoveryPointSEIEnabled; }
   Void  setToneMappingInfoSEIEnabled(Bool b)                         { m_toneMappingInfoSEIEnabled = b;  }
   Bool  getToneMappingInfoSEIEnabled()                               { return m_toneMappingInfoSEIEnabled;  }
@@ -876,6 +903,6 @@
   Void  setTMISEIExtendedWhiteLevelLumaCodeValue(Int b)              { m_extendedWhiteLevelLumaCodeValue =b;  }
   Int   getTMISEIExtendedWhiteLevelLumaCodeValue()                   { return m_extendedWhiteLevelLumaCodeValue;  }
-  Void  setFramePackingArrangementSEIEnabled(Int b)                  { m_framePackingSEIEnabled = b; }
-  Int   getFramePackingArrangementSEIEnabled()                       { return m_framePackingSEIEnabled; }
+  Void  setFramePackingArrangementSEIEnabled(Bool b)                 { m_framePackingSEIEnabled = b; }
+  Bool  getFramePackingArrangementSEIEnabled() const                 { return m_framePackingSEIEnabled; }
   Void  setFramePackingArrangementSEIType(Int b)                     { m_framePackingSEIType = b; }
   Int   getFramePackingArrangementSEIType()                          { return m_framePackingSEIType; }
@@ -886,6 +913,6 @@
   Void  setFramePackingArrangementSEIInterpretation(Int b)           { m_framePackingSEIInterpretation = b; }
   Int   getFramePackingArrangementSEIInterpretation()                { return m_framePackingSEIInterpretation; }
-  Void  setSegmentedRectFramePackingArrangementSEIEnabled(Int b)     { m_segmentedRectFramePackingSEIEnabled = b; }
-  Int   getSegmentedRectFramePackingArrangementSEIEnabled()          { return m_segmentedRectFramePackingSEIEnabled; }
+  Void  setSegmentedRectFramePackingArrangementSEIEnabled(Bool b)    { m_segmentedRectFramePackingSEIEnabled = b; }
+  Bool  getSegmentedRectFramePackingArrangementSEIEnabled() const    { return m_segmentedRectFramePackingSEIEnabled; }
   Void  setSegmentedRectFramePackingArrangementSEICancel(Int b)      { m_segmentedRectFramePackingSEICancel = b; }
   Int   getSegmentedRectFramePackingArrangementSEICancel()           { return m_segmentedRectFramePackingSEICancel; }
@@ -896,16 +923,16 @@
   Void  setDisplayOrientationSEIAngle(Int b)                         { m_displayOrientationSEIAngle = b; }
   Int   getDisplayOrientationSEIAngle()                              { return m_displayOrientationSEIAngle; }
-  Void  setTemporalLevel0IndexSEIEnabled(Int b)                      { m_temporalLevel0IndexSEIEnabled = b; }
-  Int   getTemporalLevel0IndexSEIEnabled()                           { return m_temporalLevel0IndexSEIEnabled; }
-  Void  setGradualDecodingRefreshInfoEnabled(Int b)                  { m_gradualDecodingRefreshInfoEnabled = b;    }
-  Int   getGradualDecodingRefreshInfoEnabled()                       { return m_gradualDecodingRefreshInfoEnabled; }
+  Void  setTemporalLevel0IndexSEIEnabled(Bool b)                     { m_temporalLevel0IndexSEIEnabled = b; }
+  Bool  getTemporalLevel0IndexSEIEnabled() const                     { return m_temporalLevel0IndexSEIEnabled; }
+  Void  setGradualDecodingRefreshInfoEnabled(Bool b)                 { m_gradualDecodingRefreshInfoEnabled = b;    }
+  Bool  getGradualDecodingRefreshInfoEnabled() const                 { return m_gradualDecodingRefreshInfoEnabled; }
   Void  setNoDisplaySEITLayer(Int b)                                 { m_noDisplaySEITLayer = b;    }
   Int   getNoDisplaySEITLayer()                                      { return m_noDisplaySEITLayer; }
-  Void  setDecodingUnitInfoSEIEnabled(Int b)                         { m_decodingUnitInfoSEIEnabled = b;    }
-  Int   getDecodingUnitInfoSEIEnabled()                              { return m_decodingUnitInfoSEIEnabled; }
-  Void  setSOPDescriptionSEIEnabled(Int b)                           { m_SOPDescriptionSEIEnabled = b; }
-  Int   getSOPDescriptionSEIEnabled()                                { return m_SOPDescriptionSEIEnabled; }
-  Void  setScalableNestingSEIEnabled(Int b)                          { m_scalableNestingSEIEnabled = b; }
-  Int   getScalableNestingSEIEnabled()                               { return m_scalableNestingSEIEnabled; }
+  Void  setDecodingUnitInfoSEIEnabled(Bool b)                        { m_decodingUnitInfoSEIEnabled = b;    }
+  Bool  getDecodingUnitInfoSEIEnabled() const                        { return m_decodingUnitInfoSEIEnabled; }
+  Void  setSOPDescriptionSEIEnabled(Bool b)                          { m_SOPDescriptionSEIEnabled = b; }
+  Bool  getSOPDescriptionSEIEnabled() const                          { return m_SOPDescriptionSEIEnabled; }
+  Void  setScalableNestingSEIEnabled(Bool b)                         { m_scalableNestingSEIEnabled = b; }
+  Bool  getScalableNestingSEIEnabled() const                         { return m_scalableNestingSEIEnabled; }
   Void  setTMCTSSEIEnabled(Bool b)                                   { m_tmctsSEIEnabled = b; }
   Bool  getTMCTSSEIEnabled()                                         { return m_tmctsSEIEnabled; }
@@ -939,4 +966,7 @@
   Void  setKneeSEIOutputKneePoint(Int *p)                            { m_kneeSEIOutputKneePoint = p; }
   Int*  getKneeSEIOutputKneePoint()                                  { return m_kneeSEIOutputKneePoint; }
+  Void  setColourRemapInfoSEIFileRoot( const std::string &s )        { m_colourRemapSEIFileRoot = s; }
+  const std::string &getColourRemapInfoSEIFileRoot() const           { return m_colourRemapSEIFileRoot; }
+
   Void  setMasteringDisplaySEI(const TComSEIMasteringDisplay &src)   { m_masteringDisplay = src; }
   const TComSEIMasteringDisplay &getMasteringDisplaySEI() const      { return m_masteringDisplay; }
@@ -984,8 +1014,10 @@
   Void         setUseScalingListId    ( ScalingListMode u )          { m_useScalingListId       = u;   }
   ScalingListMode getUseScalingListId    ()                          { return m_useScalingListId;      }
-  Void         setScalingListFile     ( Char*  pch )                 { m_scalingListFile     = pch; }
-  Char*        getScalingListFile     ()                             { return m_scalingListFile;    }
+  Void         setScalingListFileName       ( const std::string &s ) { m_scalingListFileName = s;      }
+  const std::string& getScalingListFileName () const                 { return m_scalingListFileName;   }
   Void         setTMVPModeId ( Int  u )                              { m_TMVPModeId = u;    }
   Int          getTMVPModeId ()                                      { return m_TMVPModeId; }
+  WeightedPredictionMethod getWeightedPredictionMethod() const       { return m_weightedPredictionMethod; }
+  Void         setWeightedPredictionMethod( WeightedPredictionMethod m ) { m_weightedPredictionMethod = m; }
   Void         setSignHideFlag( Bool signHideFlag )                  { m_signHideFlag = signHideFlag; }
   Bool         getSignHideFlag()                                     { return m_signHideFlag; }
@@ -1004,4 +1036,13 @@
   Bool         getForceIntraQP        ()                             { return m_RCForceIntraQP;        }
   Void         setForceIntraQP        ( Bool b )                     { m_RCForceIntraQP = b;           }
+
+#if U0132_TARGET_BITS_SATURATION
+  Bool         getCpbSaturationEnabled()                             { return m_RCCpbSaturationEnabled;}
+  Void         setCpbSaturationEnabled( Bool b )                     { m_RCCpbSaturationEnabled = b;   }
+  UInt         getCpbSize             ()                             { return m_RCCpbSize;}
+  Void         setCpbSize             ( UInt ui )                    { m_RCCpbSize = ui;   }
+  Double       getInitialCpbFullness  ()                             { return m_RCInitialCpbFullness;  }
+  Void         setInitialCpbFullness  (Double f)                     { m_RCInitialCpbFullness = f;     }
+#endif
 
 #if KWU_RC_MADPRED_E0227
@@ -1132,10 +1173,10 @@
   Bool         getLowerBitRateConstraintFlag() const                 { return m_lowerBitRateConstraintFlag; }
   Void         setLowerBitRateConstraintFlag(Bool b)                 { m_lowerBitRateConstraintFlag=b; }
-  Bool      getChromaSamplingFilterHintEnabled()                     { return m_chromaSamplingFilterHintEnabled;}
-  Void      setChromaSamplingFilterHintEnabled(Bool i)               { m_chromaSamplingFilterHintEnabled = i;}
-  Int       getChromaSamplingHorFilterIdc()                          { return m_chromaSamplingHorFilterIdc;}
-  Void      setChromaSamplingHorFilterIdc(Int i)                     { m_chromaSamplingHorFilterIdc = i;}
-  Int       getChromaSamplingVerFilterIdc()                          { return m_chromaSamplingVerFilterIdc;}
-  Void      setChromaSamplingVerFilterIdc(Int i)                     { m_chromaSamplingVerFilterIdc = i;}
+  Bool         getChromaResamplingFilterHintEnabled()                { return m_chromaResamplingFilterHintEnabled;}
+  Void         setChromaResamplingFilterHintEnabled(Bool i)          { m_chromaResamplingFilterHintEnabled = i;}
+  Int          getChromaResamplingHorFilterIdc()                     { return m_chromaResamplingHorFilterIdc;}
+  Void         setChromaResamplingHorFilterIdc(Int i)                { m_chromaResamplingHorFilterIdc = i;}
+  Int          getChromaResamplingVerFilterIdc()                     { return m_chromaResamplingVerFilterIdc;}
+  Void         setChromaResamplingVerFilterIdc(Int i)                { m_chromaResamplingVerFilterIdc = i;}
 
   Void      setSummaryOutFilename(const std::string &s)              { m_summaryOutFilename = s; }
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCu.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCu.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncCu.cpp	(revision 1360)
@@ -2216,5 +2216,5 @@
           *earlyDetectionSkipMode = true;
         }
-        else if(m_pcEncCfg->getFastSearch() != SELECTIVE)
+        else if(m_pcEncCfg->getMotionEstimationSearchMethod() != MESEARCH_SELECTIVE)
         {
           Int absoulte_MV=0;
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1360)
@@ -219,4 +219,15 @@
 }
 
+Void TEncGOP::xWriteAccessUnitDelimiter (AccessUnit &accessUnit, TComSlice *slice)
+{
+  AUDWriter audWriter;
+  OutputNALUnit nalu(NAL_UNIT_ACCESS_UNIT_DELIMITER);
+
+  Int picType = slice->isIntra() ? 0 : (slice->isInterP() ? 1 : 2);
+
+  audWriter.codeAUD(nalu.m_Bitstream, picType);
+  accessUnit.push_front(new NALUnitEBSP(nalu));
+}
+
 // write SEI list into one NAL unit and add it to the Access unit at auPos
 Void TEncGOP::xWriteSEI (NalUnitType naluType, SEIMessages& seiMessages, AccessUnit &accessUnit, AccessUnit::iterator &auPos, Int temporalId, const TComSPS *sps)
@@ -485,4 +496,12 @@
   }
 
+  if(m_pcCfg->getChromaResamplingFilterHintEnabled())
+  {
+    SEIChromaResamplingFilterHint *seiChromaResamplingFilterHint = new SEIChromaResamplingFilterHint;
+    m_seiEncoder.initSEIChromaResamplingFilterHint(seiChromaResamplingFilterHint, m_pcCfg->getChromaResamplingHorFilterIdc(), m_pcCfg->getChromaResamplingVerFilterIdc());
+    seiMessages.push_back(seiChromaResamplingFilterHint);
+  }
+
+
 #if NH_MV
 #if !NH_MV_SEI
@@ -545,11 +564,4 @@
   }
 
-  if(slice->getSPS()->getVuiParametersPresentFlag() && m_pcCfg->getChromaSamplingFilterHintEnabled() && ( slice->getSliceType() == I_SLICE ))
-  {
-    SEIChromaSamplingFilterHint *seiChromaSamplingFilterHint = new SEIChromaSamplingFilterHint;
-    m_seiEncoder.initSEIChromaSamplingFilterHint(seiChromaSamplingFilterHint, m_pcCfg->getChromaSamplingHorFilterIdc(), m_pcCfg->getChromaSamplingVerFilterIdc());
-    seiMessages.push_back(seiChromaSamplingFilterHint);
-  }
-
   if( m_pcEncTop->getNoDisplaySEITLayer() && ( slice->getTLayer() >= m_pcEncTop->getNoDisplaySEITLayer() ) )
   {
@@ -557,4 +569,20 @@
     seiNoDisplay->m_noDisplay = true;
     seiMessages.push_back(seiNoDisplay);
+  }
+
+  // insert one Colour Remapping Info SEI for the picture (if the file exists)
+  if (!m_pcCfg->getColourRemapInfoSEIFileRoot().empty())
+  {
+    SEIColourRemappingInfo *seiColourRemappingInfo = new SEIColourRemappingInfo();
+    const Bool success = m_seiEncoder.initSEIColourRemappingInfo(seiColourRemappingInfo, slice->getPOC() );
+
+    if(success)
+    {
+      seiMessages.push_back(seiColourRemappingInfo);
+    }
+    else
+    {
+      delete seiColourRemappingInfo;
+    }
   }
 }
@@ -577,5 +605,4 @@
 Void TEncGOP::xCreatePictureTimingSEI  (Int IRAPGOPid, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, SEIMessages& duInfoSeiMessages, TComSlice *slice, Bool isField, std::deque<DUData> &duData)
 {
-  Int picSptDpbOutputDuDelay = 0;
 #if !NH_MV
   SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
@@ -590,8 +617,6 @@
     (  hrd->getNalHrdParametersPresentFlag() || hrd->getVclHrdParametersPresentFlag() ) )
   {
-#if NH_MV
-    // Preliminary fix to avoid memory leak.
+    Int picSptDpbOutputDuDelay = 0;
     SEIPictureTiming *pictureTimingSEI = new SEIPictureTiming();
-#endif
 
     // DU parameters
@@ -712,4 +737,9 @@
       }
     }
+
+    if( !m_pcCfg->getPictureTimingSEIEnabled() && pictureTimingSEI )
+    {
+      delete pictureTimingSEI;
+    }
   }
 }
@@ -745,5 +775,5 @@
 
   // The last DU may have a trailing SEI
-  if (m_pcCfg->getDecodedPictureHashSEIEnabled())
+  if (m_pcCfg->getDecodedPictureHashSEIType()!=HASHTYPE_NONE)
   {
     duData.back().accumBitsDU += ( 20 << 3 ); // probably around 20 bytes - should be further adjusted, e.g. by type
@@ -867,10 +897,10 @@
       if (cabacZeroWordPaddingEnabled)
       {
-        std::vector<Char> zeroBytesPadding(numberOfAdditionalCabacZeroBytes, Char(0));
+        std::vector<UChar> zeroBytesPadding(numberOfAdditionalCabacZeroBytes, UChar(0));
         for(std::size_t i=0; i<numberOfAdditionalCabacZeroWords; i++)
         {
           zeroBytesPadding[i*3+2]=3;  // 00 00 03
         }
-        nalUnitData.write(&(zeroBytesPadding[0]), numberOfAdditionalCabacZeroBytes);
+        nalUnitData.write(reinterpret_cast<const TChar*>(&(zeroBytesPadding[0])), numberOfAdditionalCabacZeroBytes);
         printf("Adding %d bytes of padding\n", UInt(numberOfAdditionalCabacZeroWords*3));
       }
@@ -1058,4 +1088,37 @@
   {
     return 1;
+  }
+}
+
+
+static Void
+printHash(const HashType hashType, const std::string &digestStr)
+{
+  const TChar *decodedPictureHashModeName;
+  switch (hashType)
+  {
+    case HASHTYPE_MD5:
+      decodedPictureHashModeName = "MD5";
+      break;
+    case HASHTYPE_CRC:
+      decodedPictureHashModeName = "CRC";
+      break;
+    case HASHTYPE_CHECKSUM:
+      decodedPictureHashModeName = "Checksum";
+      break;
+    default:
+      decodedPictureHashModeName = NULL;
+      break;
+  }
+  if (decodedPictureHashModeName != NULL)
+  {
+    if (digestStr.empty())
+    {
+      printf(" [%s:%s]", decodedPictureHashModeName, "?");
+    }
+    else
+    {
+      printf(" [%s:%s]", decodedPictureHashModeName, digestStr.c_str());
+    }
   }
 }
@@ -1606,7 +1669,5 @@
 #endif
 
-    /////////////////////////////////////////////////////////////////////////////////////////////////// Compress a slice
-    //  Slice compression
-    if (m_pcCfg->getUseASR())
+    if (m_pcCfg->getUseASR() && pcSlice->getSliceType()!=I_SLICE)
     {
       m_pcSliceEncoder->setSearchRange(pcSlice);
@@ -1654,4 +1715,5 @@
       }
       m_pcRateCtrl->initRCPic( frameLevel );
+      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
 
 #if KWU_RC_MADPRED_E0227
@@ -1662,5 +1724,25 @@
 #endif
 
-      estimatedBits = m_pcRateCtrl->getRCPic()->getTargetBits();
+#if U0132_TARGET_BITS_SATURATION
+      if (m_pcRateCtrl->getCpbSaturationEnabled() && frameLevel != 0)
+      {
+        Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
+
+        // prevent overflow
+        if (estimatedCpbFullness - estimatedBits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
+        {
+          estimatedBits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
+        }
+
+        estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
+        // prevent underflow
+        if (estimatedCpbFullness - estimatedBits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
+        {
+          estimatedBits = max(200, estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f));
+        }
+
+        m_pcRateCtrl->getRCPic()->setTargetBits(estimatedBits);
+      }
+#endif
 
       Int sliceQP = m_pcCfg->getInitialQP();
@@ -1683,4 +1765,25 @@
           Int bits = m_pcRateCtrl->getRCSeq()->getLeftAverageBits();
           bits = m_pcRateCtrl->getRCPic()->getRefineBitsForIntra( bits );
+
+#if U0132_TARGET_BITS_SATURATION
+          if (m_pcRateCtrl->getCpbSaturationEnabled() )
+          {
+            Int estimatedCpbFullness = m_pcRateCtrl->getCpbState() + m_pcRateCtrl->getBufferingRate();
+
+            // prevent overflow
+            if (estimatedCpbFullness - bits > (Int)(m_pcRateCtrl->getCpbSize()*0.9f))
+            {
+              bits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.9f);
+            }
+
+            estimatedCpbFullness -= m_pcRateCtrl->getBufferingRate();
+            // prevent underflow
+            if (estimatedCpbFullness - bits < (Int)(m_pcRateCtrl->getCpbSize()*0.1f))
+            {
+              bits = estimatedCpbFullness - (Int)(m_pcRateCtrl->getCpbSize()*0.1f);
+            }
+          }
+#endif
+
           if ( bits < 200 )
           {
@@ -1835,4 +1938,8 @@
       m_bSeqFirst = false;
     }
+    if (m_pcCfg->getAccessUnitDelimiter())
+    {
+      xWriteAccessUnitDelimiter(accessUnit, pcSlice);
+    }
 
     // reset presence of BP SEI indication
@@ -2002,5 +2109,5 @@
 
     std::string digestStr;
-    if (m_pcCfg->getDecodedPictureHashSEIEnabled())
+    if (m_pcCfg->getDecodedPictureHashSEIType()!=HASHTYPE_NONE)
     {
       SEIDecodedPictureHash *decodedPictureHashSei = new SEIDecodedPictureHash();
@@ -2014,19 +2121,5 @@
     xCalculateAddPSNRs( isField, isTff, iGOPid, pcPic, accessUnit, rcListPic, dEncTime, snr_conversion, printFrameMSE );
 
-    if (!digestStr.empty())
-    {
-      if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 1)
-      {
-        printf(" [MD5:%s]", digestStr.c_str());
-      }
-      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 2)
-      {
-        printf(" [CRC:%s]", digestStr.c_str());
-      }
-      else if(m_pcCfg->getDecodedPictureHashSEIEnabled() == 3)
-      {
-        printf(" [Checksum:%s]", digestStr.c_str());
-      }
-    }
+    printHash(m_pcCfg->getDecodedPictureHashSEIType(), digestStr);
 
     if ( m_pcCfg->getUseRateCtrl() )
@@ -2051,4 +2144,11 @@
         m_pcRateCtrl->getRCGOP()->updateAfterPicture( estimatedBits );
       }
+#if U0132_TARGET_BITS_SATURATION
+      if (m_pcRateCtrl->getCpbSaturationEnabled())
+      {
+        m_pcRateCtrl->updateCpbState(actualTotalBits);
+        printf(" [CPB %6d bits]", m_pcRateCtrl->getCpbState());
+      }
+#endif
     }
 
@@ -2352,5 +2452,5 @@
   if (conversion!=IPCOLOURSPACE_UNCHANGED)
   {
-    cscd.create(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat(), pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), 0, false);
+    cscd.createWithoutCUInfo(pcPicD->getWidth(COMPONENT_Y), pcPicD->getHeight(COMPONENT_Y), pcPicD->getChromaFormat() );
     TVideoIOYuv::ColourSpaceConvert(*pcPicD, cscd, conversion, false);
   }
@@ -2452,5 +2552,5 @@
   }
 
-  Char c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
+  TChar c = (pcSlice->isIntra() ? 'I' : pcSlice->isInterP() ? 'P' : 'B');
   if (!pcSlice->isReferenced())
   {
@@ -2506,4 +2606,6 @@
   printf(" [ET %5.0f ]", dEncTime );
 
+  // printf(" [WP %d]", pcSlice->getUseWeightedPrediction());
+
   for (Int iRefList = 0; iRefList < 2; iRefList++)
   {
@@ -2555,5 +2657,5 @@
     {
       TComPicYuv &reconField=*(apcPicRecFields[fieldNum]);
-      cscd[fieldNum].create(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat(), reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), 0, false);
+      cscd[fieldNum].createWithoutCUInfo(reconField.getWidth(COMPONENT_Y), reconField.getHeight(COMPONENT_Y), reconField.getChromaFormat() );
       TVideoIOYuv::ColourSpaceConvert(reconField, cscd[fieldNum], conversion, false);
       apcPicRecFields[fieldNum]=cscd+fieldNum;
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncGOP.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncGOP.h	(revision 1360)
@@ -220,4 +220,6 @@
   Double xCalculateRVM();
 
+  Void xWriteAccessUnitDelimiter (AccessUnit &accessUnit, TComSlice *slice);
+
   Void xCreateIRAPLeadingSEIMessages (SEIMessages& seiMessages, const TComSPS *sps, const TComPPS *pps);
   Void xCreatePerPictureSEIMessages (Int picInGOP, SEIMessages& seiMessages, SEIMessages& nestedSeiMessages, TComSlice *slice);
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncPreanalyzer.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncPreanalyzer.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncPreanalyzer.cpp	(revision 1360)
@@ -87,15 +87,14 @@
         UInt64 uiSum[4] = {0, 0, 0, 0};
         UInt64 uiSumSq[4] = {0, 0, 0, 0};
-        UInt uiNumPixInAQPart = 0;
         UInt by = 0;
         for ( ; by < uiCurrAQPartHeight>>1; by++ )
         {
           UInt bx = 0;
-          for ( ; bx < uiCurrAQPartWidth>>1; bx++, uiNumPixInAQPart++ )
+          for ( ; bx < uiCurrAQPartWidth>>1; bx++ )
           {
             uiSum  [0] += pBlkY[bx];
             uiSumSq[0] += pBlkY[bx] * pBlkY[bx];
           }
-          for ( ; bx < uiCurrAQPartWidth; bx++, uiNumPixInAQPart++ )
+          for ( ; bx < uiCurrAQPartWidth; bx++ )
           {
             uiSum  [1] += pBlkY[bx];
@@ -107,10 +106,10 @@
         {
           UInt bx = 0;
-          for ( ; bx < uiCurrAQPartWidth>>1; bx++, uiNumPixInAQPart++ )
+          for ( ; bx < uiCurrAQPartWidth>>1; bx++ )
           {
             uiSum  [2] += pBlkY[bx];
             uiSumSq[2] += pBlkY[bx] * pBlkY[bx];
           }
-          for ( ; bx < uiCurrAQPartWidth; bx++, uiNumPixInAQPart++ )
+          for ( ; bx < uiCurrAQPartWidth; bx++ )
           {
             uiSum  [3] += pBlkY[bx];
@@ -120,10 +119,23 @@
         }
 
+        assert ((uiCurrAQPartWidth&1)==0);
+        assert ((uiCurrAQPartHeight&1)==0);
+        const UInt pixelWidthOfQuadrants  = uiCurrAQPartWidth >>1;
+        const UInt pixelHeightOfQuadrants = uiCurrAQPartHeight>>1;
+        const UInt numPixInAQPart         = pixelWidthOfQuadrants * pixelHeightOfQuadrants;
+
         Double dMinVar = DBL_MAX;
+        if (numPixInAQPart!=0)
+        {
         for ( Int i=0; i<4; i++)
         {
-          const Double dAverage = Double(uiSum[i]) / uiNumPixInAQPart;
-          const Double dVariance = Double(uiSumSq[i]) / uiNumPixInAQPart - dAverage * dAverage;
+            const Double dAverage = Double(uiSum[i]) / numPixInAQPart;
+            const Double dVariance = Double(uiSumSq[i]) / numPixInAQPart - dAverage * dAverage;
           dMinVar = min(dMinVar, dVariance);
+        }
+        }
+        else
+        {
+          dMinVar = 0.0;
         }
         const Double dActivity = 1.0 + dMinVar;
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncRateCtrl.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncRateCtrl.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncRateCtrl.cpp	(revision 1360)
@@ -1639,4 +1639,10 @@
     m_encRCSeq->initLCUPara();
   }
+#if U0132_TARGET_BITS_SATURATION
+  m_CpbSaturationEnabled = false;
+  m_cpbSize              = targetBitrate;
+  m_cpbState             = (UInt)(m_cpbSize*0.5f);
+  m_bufferingRate        = (Int)(targetBitrate / frameRate);
+#endif
 
 #if KWU_RC_MADPRED_E0227
@@ -1664,4 +1670,34 @@
 }
 
+#if U0132_TARGET_BITS_SATURATION
+Int  TEncRateCtrl::updateCpbState(Int actualBits)
+{
+  Int cpbState = 1;
+
+  m_cpbState -= actualBits;
+  if (m_cpbState < 0)
+  {
+    cpbState = -1;
+  }
+
+  m_cpbState += m_bufferingRate;
+  if (m_cpbState > m_cpbSize)
+  {
+    cpbState = 0;
+  }
+
+  return cpbState;
+}
+
+Void TEncRateCtrl::initHrdParam(const TComHRD* pcHrd, Int iFrameRate, Double fInitialCpbFullness)
+{
+  m_CpbSaturationEnabled = true;
+  m_cpbSize = (pcHrd->getCpbSizeValueMinus1(0, 0, 0) + 1) << (4 + pcHrd->getCpbSizeScale());
+  m_cpbState = (UInt)(m_cpbSize*fInitialCpbFullness);
+  m_bufferingRate = (UInt)(((pcHrd->getBitRateValueMinus1(0, 0, 0) + 1) << (6 + pcHrd->getBitRateScale())) / iFrameRate);
+  printf("\nHRD - [Initial CPB state %6d] [CPB Size %6d] [Buffering Rate %6d]\n", m_cpbState, m_cpbSize, m_bufferingRate);
+}
+#endif
+
 Void TEncRateCtrl::destroyRCGOP()
 {
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncRateCtrl.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncRateCtrl.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncRateCtrl.h	(revision 1360)
@@ -285,4 +285,7 @@
   TRCLCU& getLCU( Int LCUIdx )                            { return m_LCUs[LCUIdx]; }
   Int  getPicActualHeaderBits()                           { return m_picActualHeaderBits; }
+#if U0132_TARGET_BITS_SATURATION
+  Void setBitLeft(Int bits)                               { m_bitsLeft = bits; }
+#endif
   Void setTargetBits( Int bits )                          { m_targetBits = bits; m_bitsLeft = bits;}
   Void setTotalIntraCost(Double cost)                     { m_totalCostIntra = cost; }
@@ -369,4 +372,13 @@
   Void setLayerID(Int layerid)     { m_LayerID = layerid; }
 #endif
+#if U0132_TARGET_BITS_SATURATION
+  Bool       getCpbSaturationEnabled()  { return m_CpbSaturationEnabled;  }
+  UInt       getCpbState()              { return m_cpbState;       }
+  UInt       getCpbSize()               { return m_cpbSize;        }
+  UInt       getBufferingRate()         { return m_bufferingRate;  }
+  Int        updateCpbState(Int actualBits);
+  Void       initHrdParam(const TComHRD* pcHrd, Int iFrameRate, Double fInitialCpbFullness);
+#endif
+
 private:
   TEncRCSeq* m_encRCSeq;
@@ -375,4 +387,11 @@
   list<TEncRCPic*> m_listRCPictures;
   Int        m_RCQP;
+#if U0132_TARGET_BITS_SATURATION
+  Bool       m_CpbSaturationEnabled;    // Enable target bits saturation to avoid CPB overflow and underflow
+  Int        m_cpbState;                // CPB State 
+  UInt       m_cpbSize;                 // CPB size
+  UInt       m_bufferingRate;           // Buffering rate
+#endif
+
 #if KWU_RC_MADPRED_E0227
   Int m_LayerID;
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 1360)
@@ -908,5 +908,5 @@
       m_signLineBuf1 = NULL;
     }
-    m_signLineBuf1 = new Char[m_lineBufWidth+1];
+    m_signLineBuf1 = new SChar[m_lineBufWidth+1];
 
     if (m_signLineBuf2)
@@ -915,9 +915,9 @@
       m_signLineBuf2 = NULL;
     }
-    m_signLineBuf2 = new Char[m_lineBufWidth+1];
+    m_signLineBuf2 = new SChar[m_lineBufWidth+1];
   }
 
   Int x,y, startX, startY, endX, endY, edgeType, firstLineStartX, firstLineEndX;
-  Char signLeft, signRight, signDown;
+  SChar signLeft, signRight, signDown;
   Int64 *diff, *count;
   Pel *srcLine, *orgLine;
@@ -949,8 +949,8 @@
         for (y=0; y<endY; y++)
         {
-          signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
+          signLeft = (SChar)sgn(srcLine[startX] - srcLine[startX-1]);
           for (x=startX; x<endX; x++)
           {
-            signRight =  (Char)sgn(srcLine[x] - srcLine[x+1]);
+            signRight =  (SChar)sgn(srcLine[x] - srcLine[x+1]);
             edgeType  =  signRight + signLeft;
             signLeft  = -signRight;
@@ -971,8 +971,8 @@
             for(y=0; y<skipLinesB[typeIdx]; y++)
             {
-              signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
+              signLeft = (SChar)sgn(srcLine[startX] - srcLine[startX-1]);
               for (x=startX; x<endX; x++)
               {
-                signRight =  (Char)sgn(srcLine[x] - srcLine[x+1]);
+                signRight =  (SChar)sgn(srcLine[x] - srcLine[x+1]);
                 edgeType  =  signRight + signLeft;
                 signLeft  = -signRight;
@@ -992,5 +992,5 @@
         diff +=2;
         count+=2;
-        Char *signUpLine = m_signLineBuf1;
+        SChar *signUpLine = m_signLineBuf1;
 
         startX = (!isCalculatePreDeblockSamples) ? 0
@@ -1011,5 +1011,5 @@
         for (x=startX; x<endX; x++)
         {
-          signUpLine[x] = (Char)sgn(srcLine[x] - srcLineAbove[x]);
+          signUpLine[x] = (SChar)sgn(srcLine[x] - srcLineAbove[x]);
         }
 
@@ -1021,5 +1021,5 @@
           for (x=startX; x<endX; x++)
           {
-            signDown  = (Char)sgn(srcLine[x] - srcLineBelow[x]); 
+            signDown  = (SChar)sgn(srcLine[x] - srcLineBelow[x]);
             edgeType  = signDown + signUpLine[x];
             signUpLine[x]= -signDown;
@@ -1061,5 +1061,5 @@
         diff +=2;
         count+=2;
-        Char *signUpLine, *signDownLine, *signTmpLine;
+        SChar *signUpLine, *signDownLine, *signTmpLine;
 
         signUpLine  = m_signLineBuf1;
@@ -1079,5 +1079,5 @@
         for (x=startX; x<endX+1; x++)
         {
-          signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x-1]);
+          signUpLine[x] = (SChar)sgn(srcLineBelow[x] - srcLine[x-1]);
         }
 
@@ -1103,5 +1103,5 @@
           for (x=startX; x<endX; x++)
           {
-            signDown = (Char)sgn(srcLine[x] - srcLineBelow[x+1]);
+            signDown = (SChar)sgn(srcLine[x] - srcLineBelow[x+1]);
             edgeType = signDown + signUpLine[x];
             diff [edgeType] += (orgLine[x] - srcLine[x]);
@@ -1110,5 +1110,5 @@
             signDownLine[x+1] = -signDown;
           }
-          signDownLine[startX] = (Char)sgn(srcLineBelow[startX] - srcLine[startX-1]);
+          signDownLine[startX] = (SChar)sgn(srcLineBelow[startX] - srcLine[startX-1]);
 
           signTmpLine  = signUpLine;
@@ -1148,5 +1148,5 @@
         diff +=2;
         count+=2;
-        Char *signUpLine = m_signLineBuf1+1;
+        SChar *signUpLine = m_signLineBuf1+1;
 
         startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
@@ -1162,5 +1162,5 @@
         for (x=startX-1; x<endX; x++)
         {
-          signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x+1]);
+          signUpLine[x] = (SChar)sgn(srcLineBelow[x] - srcLine[x+1]);
         }
 
@@ -1191,5 +1191,5 @@
           for(x=startX; x<endX; x++)
           {
-            signDown = (Char)sgn(srcLine[x] - srcLineBelow[x-1]);
+            signDown = (SChar)sgn(srcLine[x] - srcLineBelow[x-1]);
             edgeType = signDown + signUpLine[x];
 
@@ -1199,5 +1199,5 @@
             signUpLine[x-1] = -signDown;
           }
-          signUpLine[endX-1] = (Char)sgn(srcLineBelow[endX-1] - srcLine[endX]);
+          signUpLine[endX-1] = (SChar)sgn(srcLineBelow[endX-1] - srcLine[endX]);
           srcLine  += srcStride;
           orgLine  += orgStride;
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSearch.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSearch.cpp	(revision 1360)
@@ -74,11 +74,4 @@
 };
 
-static const UInt s_auiDFilter[9] =
-{
-  0, 1, 0,
-  2, 3, 2,
-  0, 1, 0
-};
-
 static Void offsetSubTUCBFs(TComTU &rTu, const ComponentID compID)
 {
@@ -120,9 +113,7 @@
 , m_iSearchRange (0)
 , m_bipredSearchRange (0)
-, m_iFastSearch (0)
 , m_pppcRDSbacCoder (NULL)
 , m_pcRDGoOnSbacCoder (NULL)
 , m_pTempPel (NULL)
-, m_puiDFilter (NULL)
 , m_isInitialized (false)
 {
@@ -130,8 +121,6 @@
   {
     m_ppcQTTempCoeff[ch]                           = NULL;
-    m_pcQTTempCoeff[ch]                            = NULL;
 #if ADAPTIVE_QP_SELECTION
     m_ppcQTTempArlCoeff[ch]                        = NULL;
-    m_pcQTTempArlCoeff[ch]                         = NULL;
 #endif
     m_puhQTTempCbf[ch]                             = NULL;
@@ -181,9 +170,7 @@
       }
       delete[] m_ppcQTTempCoeff[ch];
-      delete[] m_pcQTTempCoeff[ch];
       delete[] m_puhQTTempCbf[ch];
 #if ADAPTIVE_QP_SELECTION
       delete[] m_ppcQTTempArlCoeff[ch];
-      delete[] m_pcQTTempArlCoeff[ch];
 #endif
     }
@@ -229,5 +216,5 @@
                       Int           iSearchRange,
                       Int           bipredSearchRange,
-                      Int           iFastSearch,
+                      MESearchMethod motionEstimationSearchMethod,
                       const UInt    maxCUWidth,
                       const UInt    maxCUHeight,
@@ -244,5 +231,5 @@
   m_iSearchRange         = iSearchRange;
   m_bipredSearchRange    = bipredSearchRange;
-  m_iFastSearch          = iFastSearch;
+  m_motionEstimationSearchMethod = motionEstimationSearchMethod;
   m_pcEntropyCoder       = pcEntropyCoder;
   m_pcRdCost             = pcRdCost;
@@ -258,6 +245,4 @@
     }
   }
-
-  m_puiDFilter = s_auiDFilter + 4;
 
   // initialize motion cost
@@ -289,8 +274,6 @@
     const UInt csy=::getComponentScaleY(ComponentID(ch), cform);
     m_ppcQTTempCoeff[ch] = new TCoeff* [uiNumLayersToAllocate];
-    m_pcQTTempCoeff[ch]   = new TCoeff [(maxCUWidth*maxCUHeight)>>(csx+csy)   ];
 #if ADAPTIVE_QP_SELECTION
     m_ppcQTTempArlCoeff[ch]  = new TCoeff*[uiNumLayersToAllocate];
-    m_pcQTTempArlCoeff[ch]   = new TCoeff [(maxCUWidth*maxCUHeight)>>(csx+csy)   ];
 #endif
     m_puhQTTempCbf[ch] = new UChar  [uiNumPartitions];
@@ -304,5 +287,5 @@
     }
 
-    m_phQTTempCrossComponentPredictionAlpha[ch]    = new Char  [uiNumPartitions];
+    m_phQTTempCrossComponentPredictionAlpha[ch]    = new SChar  [uiNumPartitions];
     m_pSharedPredTransformSkip[ch]                 = new Pel   [MAX_CU_SIZE*MAX_CU_SIZE];
     m_pcQTTempTUCoeff[ch]                          = new TCoeff[MAX_CU_SIZE*MAX_CU_SIZE];
@@ -323,46 +306,13 @@
 }
 
-#define TZ_SEARCH_CONFIGURATION                                                                                 \
-const Int  iRaster                  = 5;  /* TZ soll von aussen ?ergeben werden */                            \
-const Bool bTestOtherPredictedMV    = 0;                                                                      \
-const Bool bTestZeroVector          = 1;                                                                      \
-const Bool bTestZeroVectorStart     = 0;                                                                      \
-const Bool bTestZeroVectorStop      = 0;                                                                      \
-const Bool bFirstSearchDiamond      = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
-const Bool bFirstSearchStop         = m_pcEncCfg->getFastMEAssumingSmootherMVEnabled();                       \
-const UInt uiFirstSearchRounds      = 3;  /* first search stop X rounds after best match (must be >=1) */     \
-const Bool bEnableRasterSearch      = 1;                                                                      \
-const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 2 slower ===== */                     \
-const Bool bRasterRefinementEnable  = 0;  /* enable either raster refinement or star refinement */            \
-const Bool bRasterRefinementDiamond = 0;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
-const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */            \
-const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */        \
-const Bool bStarRefinementStop      = 0;                                                                      \
-const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */  \
-
-
-#define SEL_SEARCH_CONFIGURATION                                                                                 \
-  const Bool bTestOtherPredictedMV    = 1;                                                                       \
-  const Bool bTestZeroVector          = 1;                                                                       \
-  const Bool bEnableRasterSearch      = 1;                                                                       \
-  const Bool bAlwaysRasterSearch      = 0;  /* ===== 1: BETTER but factor 15x slower ===== */                    \
-  const Bool bStarRefinementEnable    = 1;  /* enable either star refinement or raster refinement */             \
-  const Bool bStarRefinementDiamond   = 1;  /* 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch */         \
-  const Bool bStarRefinementStop      = 0;                                                                       \
-  const UInt uiStarRefinementRounds   = 2;  /* star refinement stop X rounds after best match (must be >=1) */   \
-  const UInt uiSearchRange            = m_iSearchRange;                                                          \
-  const Int  uiSearchRangeInitial     = m_iSearchRange >> 2;                                                     \
-  const Int  uiSearchStep             = 4;                                                                       \
-  const Int  iMVDistThresh            = 8;                                                                       \
-
-
-
-__inline Void TEncSearch::xTZSearchHelp( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
+
+
+
+__inline Void TEncSearch::xTZSearchHelp( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance )
 {
   Distortion  uiSad = 0;
 
-  Pel*  piRefSrch;
-
-  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
+  const Pel* const  piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iYStride + iSearchX;
+
 #if NH_3D_IC
   m_cDistParam.bUseIC = pcPatternKey->getICFlag();
@@ -374,26 +324,19 @@
   m_pcRdCost->setDistParam( pcPatternKey, piRefSrch, rcStruct.iYStride,  m_cDistParam );
 
-  if(m_pcEncCfg->getFastSearch() != SELECTIVE)
-  {
-    // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
-    if ( m_pcEncCfg->getUseFastEnc() )
-    {
-      if ( m_cDistParam.iRows > 8 )
-      {
-        m_cDistParam.iSubShift = 1;
-      }
-    }
-  }
-
   setDistParamComp(COMPONENT_Y);
 
   // distortion
   m_cDistParam.bitDepth = pcPatternKey->getBitDepthY();
-  if(m_pcEncCfg->getFastSearch() == SELECTIVE)
+  m_cDistParam.m_maximumDistortionForEarlyExit = rcStruct.uiBestSad;
+
+  if((m_pcEncCfg->getRestrictMESampling() == false) && m_pcEncCfg->getMotionEstimationSearchMethod() == MESEARCH_SELECTIVE)
   {
     Int isubShift = 0;
     // motion cost
-    Distortion uiBitCost = m_pcRdCost->getCost( iSearchX, iSearchY );
-
+    Distortion uiBitCost = m_pcRdCost->getCostOfVectorWithPredictor( iSearchX, iSearchY );
+
+    // Skip search if bit cost is already larger than best SAD
+    if (uiBitCost < rcStruct.uiBestSad)
+    {
     if ( m_cDistParam.iRows > 32 )
     {
@@ -443,4 +386,6 @@
           rcStruct.uiBestRound    = 0;
           rcStruct.ucPointNr      = ucPointNr;
+            m_cDistParam.m_maximumDistortionForEarlyExit = uiSad;
+          }
         }
       }
@@ -449,8 +394,21 @@
   else
   {
+    // fast encoder decision: use subsampled SAD when rows > 8 for integer ME
+    if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE3 )
+    {
+      if ( m_cDistParam.iRows > 8 )
+      {
+        m_cDistParam.iSubShift = 1;
+      }
+    }
+
     uiSad = m_cDistParam.DistFunc( &m_cDistParam );
 
+    // only add motion cost if uiSad is smaller than best. Otherwise pointless
+    // to add motion cost.
+    if( uiSad < rcStruct.uiBestSad )
+    {
     // motion cost
-    uiSad += m_pcRdCost->getCost( iSearchX, iSearchY );
+      uiSad += m_pcRdCost->getCostOfVectorWithPredictor( iSearchX, iSearchY );
 
     if( uiSad < rcStruct.uiBestSad )
@@ -462,4 +420,6 @@
       rcStruct.uiBestRound    = 0;
       rcStruct.ucPointNr      = ucPointNr;
+        m_cDistParam.m_maximumDistortionForEarlyExit = uiSad;
+      }
     }
   }
@@ -469,5 +429,5 @@
 
 
-__inline Void TEncSearch::xTZ2PointSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB )
+__inline Void TEncSearch::xTZ2PointSearch( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const TComMv* const pcMvSrchRngLT, const TComMv* const pcMvSrchRngRB )
 {
   Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
@@ -602,10 +562,10 @@
 
 
-__inline Void TEncSearch::xTZ8PointSquareSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
+__inline Void TEncSearch::xTZ8PointSquareSearch( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const TComMv* const pcMvSrchRngLT, const TComMv* const pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
 {
-  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
-  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
-  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
-  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
+  const Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
+  const Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
+  const Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
+  const Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
 
   // 8 point search,                   //   1 2 3
@@ -660,10 +620,17 @@
 
 
-__inline Void TEncSearch::xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist )
+__inline Void TEncSearch::xTZ8PointDiamondSearch( const TComPattern*const  pcPatternKey,
+                                                  IntTZSearchStruct& rcStruct,
+                                                  const TComMv*const  pcMvSrchRngLT,
+                                                  const TComMv*const  pcMvSrchRngRB,
+                                                  const Int iStartX,
+                                                  const Int iStartY,
+                                                  const Int iDist,
+                                                  const Bool bCheckCornersAtDist1 )
 {
-  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
-  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
-  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
-  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
+  const Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
+  const Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
+  const Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
+  const Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
 
   // 8 point search,                   //   1 2 3
@@ -677,10 +644,25 @@
   rcStruct.uiBestRound += 1;
 
-  if ( iDist == 1 ) // iDist == 1
+  if ( iDist == 1 )
   {
     if ( iTop >= iSrchRngVerTop ) // check top
     {
+      if (bCheckCornersAtDist1)
+      {
+        if ( iLeft >= iSrchRngHorLeft) // check top-left
+        {
+          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iTop, 1, iDist );
+        }
+        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
+        if ( iRight <= iSrchRngHorRight ) // check middle right
+        {
+          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iTop, 3, iDist );
+        }
+      }
+      else
+      {
       xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iTop, 2, iDist );
     }
+    }
     if ( iLeft >= iSrchRngHorLeft ) // check middle left
     {
@@ -693,8 +675,23 @@
     if ( iBottom <= iSrchRngVerBottom ) // check bottom
     {
+      if (bCheckCornersAtDist1)
+      {
+        if ( iLeft >= iSrchRngHorLeft) // check top-left
+        {
+          xTZSearchHelp( pcPatternKey, rcStruct, iLeft, iBottom, 6, iDist );
+        }
+        xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
+        if ( iRight <= iSrchRngHorRight ) // check middle right
+        {
+          xTZSearchHelp( pcPatternKey, rcStruct, iRight, iBottom, 8, iDist );
+        }
+      }
+      else
+      {
       xTZSearchHelp( pcPatternKey, rcStruct, iStartX, iBottom, 7, iDist );
     }
   }
-  else // if (iDist != 1)
+  }
+  else
   {
     if ( iDist <= 8 )
@@ -770,8 +767,8 @@
         for ( Int index = 1; index < 4; index++ )
         {
-          Int iPosYT = iTop    + ((iDist>>2) * index);
-          Int iPosYB = iBottom - ((iDist>>2) * index);
-          Int iPosXL = iStartX - ((iDist>>2) * index);
-          Int iPosXR = iStartX + ((iDist>>2) * index);
+          const Int iPosYT = iTop    + ((iDist>>2) * index);
+          const Int iPosYB = iBottom - ((iDist>>2) * index);
+          const Int iPosXL = iStartX - ((iDist>>2) * index);
+          const Int iPosXR = iStartX + ((iDist>>2) * index);
           xTZSearchHelp( pcPatternKey, rcStruct, iPosXL, iPosYT, 0, iDist );
           xTZSearchHelp( pcPatternKey, rcStruct, iPosXR, iPosYT, 0, iDist );
@@ -800,8 +797,8 @@
         for ( Int index = 1; index < 4; index++ )
         {
-          Int iPosYT = iTop    + ((iDist>>2) * index);
-          Int iPosYB = iBottom - ((iDist>>2) * index);
-          Int iPosXL = iStartX - ((iDist>>2) * index);
-          Int iPosXR = iStartX + ((iDist>>2) * index);
+          const Int iPosYT = iTop    + ((iDist>>2) * index);
+          const Int iPosYB = iBottom - ((iDist>>2) * index);
+          const Int iPosXL = iStartX - ((iDist>>2) * index);
+          const Int iPosXR = iStartX + ((iDist>>2) * index);
 
           if ( iPosYT >= iSrchRngVerTop ) // check top
@@ -833,10 +830,4 @@
 }
 
-
-
-
-
-//<--
-
 Distortion TEncSearch::xPatternRefinement( TComPattern* pcPatternKey,
                                            TComMv baseRefMv,
@@ -886,5 +877,5 @@
     m_cDistParam.bitDepth = pcPatternKey->getBitDepthY();
     uiDist = m_cDistParam.DistFunc( &m_cDistParam );
-    uiDist += m_pcRdCost->getCost( cMvTest.getHor(), cMvTest.getVer() );
+    uiDist += m_pcRdCost->getCostOfVectorWithPredictor( cMvTest.getHor(), cMvTest.getVer() );
 
     if ( uiDist < uiDistBest )
@@ -892,4 +883,5 @@
       uiDistBest  = uiDist;
       uiDirecBest = i;
+      m_cDistParam.m_maximumDistortionForEarlyExit = uiDist;
     }
   }
@@ -2410,5 +2402,5 @@
 }
 
-Char
+SChar
 TEncSearch::xCalcCrossComponentPredictionAlpha(       TComTU &rTu,
                                                 const ComponentID compID,
@@ -2427,5 +2419,5 @@
   const Int diffBitDepth = pCU->getSlice()->getSPS()->getDifferentialLumaChromaBitDepth();
 
-  Char alpha = 0;
+  SChar alpha = 0;
   Int SSxy  = 0;
   Int SSxx  = 0;
@@ -2447,7 +2439,7 @@
   {
     Double dAlpha = SSxy / Double( SSxx );
-    alpha = Char(Clip3<Int>(-16, 16, (Int)(dAlpha * 16)));
-
-    static const Char alphaQuant[17] = {0, 1, 1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8};
+    alpha = SChar(Clip3<Int>(-16, 16, (Int)(dAlpha * 16)));
+
+    static const SChar alphaQuant[17] = {0, 1, 1, 2, 2, 2, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8};
 
     alpha = (alpha < 0) ? -alphaQuant[Int(-alpha)] : alphaQuant[Int(alpha)];
@@ -2540,5 +2532,5 @@
         Double     singleCostTmp             = 0;
         UInt       singleCbfCTmp             = 0;
-        Char       bestCrossCPredictionAlpha = 0;
+        SChar      bestCrossCPredictionAlpha = 0;
         Int        bestTransformSkipMode     = 0;
 
@@ -3689,5 +3681,5 @@
               ::memcpy( m_puhQTTempCbf[compID], pcCU->getCbf( compID )+uiPartOffset, uiQPartNum * sizeof( UChar ) );
               ::memcpy( m_puhQTTempTransformSkipFlag[compID], pcCU->getTransformSkip( compID )+uiPartOffset, uiQPartNum * sizeof( UChar ) );
-              ::memcpy( m_phQTTempCrossComponentPredictionAlpha[compID], pcCU->getCrossComponentPredictionAlpha(compID)+uiPartOffset, uiQPartNum * sizeof( Char ) );
+              ::memcpy( m_phQTTempCrossComponentPredictionAlpha[compID], pcCU->getCrossComponentPredictionAlpha(compID)+uiPartOffset, uiQPartNum * sizeof( SChar ) );
             }
           }
@@ -3702,5 +3694,5 @@
           ::memcpy( pcCU->getCbf( compID )+uiPartOffset, m_puhQTTempCbf[compID], uiQPartNum * sizeof( UChar ) );
           ::memcpy( pcCU->getTransformSkip( compID )+uiPartOffset, m_puhQTTempTransformSkipFlag[compID], uiQPartNum * sizeof( UChar ) );
-          ::memcpy( pcCU->getCrossComponentPredictionAlpha(compID)+uiPartOffset, m_phQTTempCrossComponentPredictionAlpha[compID], uiQPartNum * sizeof( Char ) );
+          ::memcpy( pcCU->getCrossComponentPredictionAlpha(compID)+uiPartOffset, m_phQTTempCrossComponentPredictionAlpha[compID], uiQPartNum * sizeof( SChar ) );
         }
       }
@@ -3812,5 +3804,5 @@
 {
   UInt        uiDepth      = pcCU->getDepth(0);
-  const UInt  uiDistortion = 0;
+  const Distortion  uiDistortion = 0;
   UInt        uiBits;
 
@@ -4325,5 +4317,5 @@
             /*correct the bit-rate part of the current ref*/
             m_pcRdCost->setPredictor  ( cMvPred[iRefList][iRefIdxTemp] );
-            uiBitsTemp += m_pcRdCost->getBits( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
+            uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() );
             /*calculate the correct cost*/
             uiCostTemp += m_pcRdCost->getCost( uiBitsTemp );
@@ -4374,5 +4366,5 @@
     }
 
-    //  Bi-directional prediction
+    //  Bi-predictive Motion estimation
     if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false) )
     {
@@ -4429,5 +4421,5 @@
 
       // fast encoder setting: only one iteration
-      if ( m_pcEncCfg->getUseFastEnc() || pcCU->getSlice()->getMvdL1ZeroFlag())
+      if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || pcCU->getSlice()->getMvdL1ZeroFlag() )
       {
         iNumIter = 1;
@@ -4438,5 +4430,5 @@
         Int         iRefList    = iIter % 2;
 
-        if ( m_pcEncCfg->getUseFastEnc() )
+        if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 )
         {
           if( uiCost[0] <= uiCost[1] )
@@ -4629,5 +4621,5 @@
       TComMvField cMEMvField[2];
 
-      m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
+      m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
 
 #if AMP_MRG
@@ -4652,6 +4644,6 @@
       // save ME result.
       uiMEInterDir = pcCU->getInterDir( uiPartAddr );
-      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
-      pcCU->getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
+      TComDataCU::getMvField( pcCU, uiPartAddr, REF_PIC_LIST_0, cMEMvField[0] );
+      TComDataCU::getMvField( pcCU, uiPartAddr, REF_PIC_LIST_1, cMEMvField[1] );
 
       // find Merge result
@@ -5040,5 +5032,5 @@
   }
 
-  m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(0) );
+  m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(0) );
   m_pcRdCost->setCostScale ( 0    );
 
@@ -5046,5 +5038,5 @@
 
   m_pcRdCost->setPredictor( rcMvPred );
-  Int iOrgMvBits  = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
+  Int iOrgMvBits  = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer());
   iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS];
   Int iBestMvBits = iOrgMvBits;
@@ -5059,5 +5051,5 @@
     m_pcRdCost->setPredictor( pcAMVPInfo->m_acMvCand[iMVPIdx] );
 
-    Int iMvBits = m_pcRdCost->getBits(cMv.getHor(), cMv.getVer());
+    Int iMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer());
     iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS];
 
@@ -5134,5 +5126,5 @@
 
   uiCost = m_pcRdCost->getDistPart( pcCU->getSlice()->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA), pcTemplateCand->getAddr(COMPONENT_Y, uiPartAddr), pcTemplateCand->getStride(COMPONENT_Y), pcOrgYuv->getAddr(COMPONENT_Y, uiPartAddr), pcOrgYuv->getStride(COMPONENT_Y), iSizeX, iSizeY, COMPONENT_Y, DF_SAD );
-  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, false, DF_SAD );
+  uiCost = (UInt) m_pcRdCost->calcRdCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum], uiCost, DF_SAD );
   return uiCost;
 }
@@ -5176,5 +5168,5 @@
 #endif
 
-  if ( bBi )
+  if ( bBi ) // Bipredictive ME
   {
     TComYuv*  pcYuvOther = &m_acYuvPred[1-(Int)eRefPicList];
@@ -5187,4 +5179,5 @@
     fWeight = 0.5;
   }
+  m_cDistParam.bIsBiPred = bBi;
 
   //  Search key pattern initialization
@@ -5212,5 +5205,5 @@
   }
 
-  m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
+  m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
 
   m_pcRdCost->setPredictor  ( *pcMvPred );
@@ -5231,5 +5224,5 @@
   setWpScalingDistParam( pcCU, iRefIdxPred, eRefPicList );
   //  Do integer search
-  if ( !m_iFastSearch || bBi )
+  if ( (m_motionEstimationSearchMethod==MESEARCH_FULL) || bBi )
   {
     xPatternSearch      ( pcPatternKey, piRefY, iRefStride, &cMvSrchRngLT, &cMvSrchRngRB, rcMv, ruiCost );
@@ -5250,5 +5243,5 @@
   }
 
-  m_pcRdCost->getMotionCost( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
+  m_pcRdCost->selectMotionLambda( true, 0, pcCU->getCUTransquantBypass(uiPartAddr) );
 #if NH_3D_INTEGER_MV_DEPTH
   if( ! pcCU->getSlice()->getIsDepth() )
@@ -5268,5 +5261,5 @@
 #endif
 
-  UInt uiMvBits = m_pcRdCost->getBits( rcMv.getHor(), rcMv.getVer() );
+  UInt uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor( rcMv.getHor(), rcMv.getVer() );
 #if NH_3D_INTEGER_MV_DEPTH
   if( pcCU->getSlice()->getIsDepth() )
@@ -5285,5 +5278,6 @@
 
 
-Void TEncSearch::xSetSearchRange ( TComDataCU* pcCU, TComMv& cMvPred, Int iSrchRng, TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
+Void TEncSearch::xSetSearchRange ( const TComDataCU* const pcCU, const TComMv& cMvPred, const Int iSrchRng,
+                                   TComMv& rcMvSrchRngLT, TComMv& rcMvSrchRngRB )
 {
   Int  iMvShift = 2;
@@ -5317,12 +5311,21 @@
   pcCU->clipMv        ( rcMvSrchRngRB );
 
+#if ME_ENABLE_ROUNDING_OF_MVS
+  rcMvSrchRngLT.divideByPowerOf2(iMvShift);
+  rcMvSrchRngRB.divideByPowerOf2(iMvShift);
+#else
   rcMvSrchRngLT >>= iMvShift;
   rcMvSrchRngRB >>= iMvShift;
+#endif
 }
 
 
-
-
-Void TEncSearch::xPatternSearch( TComPattern* pcPatternKey, Pel* piRefY, Int iRefStride, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, TComMv& rcMv, Distortion& ruiSAD )
+Void TEncSearch::xPatternSearch( const TComPattern* const pcPatternKey,
+                                 const Pel*               piRefY,
+                                 const Int                iRefStride,
+                                 const TComMv* const      pcMvSrchRngLT,
+                                 const TComMv* const      pcMvSrchRngRB,
+                                 TComMv&      rcMv,
+                                 Distortion&  ruiSAD )
 {
   Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
@@ -5336,11 +5339,9 @@
   Int         iBestY = 0;
 
-  Pel*  piRefSrch;
-
   //-- jclee for using the SAD function pointer
   m_pcRdCost->setDistParam( pcPatternKey, piRefY, iRefStride,  m_cDistParam );
 
   // fast encoder decision: use subsampled SAD for integer ME
-  if ( m_pcEncCfg->getUseFastEnc() )
+  if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE3 )
   {
     if ( m_cDistParam.iRows > 8 )
@@ -5356,6 +5357,5 @@
     {
       //  find min. distortion position
-      piRefSrch = piRefY + x;
-      m_cDistParam.pCur = piRefSrch;
+      m_cDistParam.pCur = piRefY + x;
 
       setDistParamComp(COMPONENT_Y);
@@ -5373,5 +5373,5 @@
 
       // motion cost
-      uiSad += m_pcRdCost->getCost( x, y );
+      uiSad += m_pcRdCost->getCostOfVectorWithPredictor( x, y );
 
       if ( uiSad < uiSadBest )
@@ -5380,4 +5380,5 @@
         iBestX    = x;
         iBestY    = y;
+        m_cDistParam.m_maximumDistortionForEarlyExit = uiSad;
       }
     }
@@ -5387,5 +5388,5 @@
   rcMv.set( iBestX, iBestY );
 
-  ruiSAD = uiSadBest - m_pcRdCost->getCost( iBestX, iBestY );
+  ruiSAD = uiSadBest - m_pcRdCost->getCostOfVectorWithPredictor( iBestX, iBestY );
   return;
 }
@@ -5393,13 +5394,13 @@
 
 
-Void TEncSearch::xPatternSearchFast( TComDataCU*   pcCU,
-                                     TComPattern*  pcPatternKey,
-                                     Pel*          piRefY,
-                                     Int           iRefStride,
-                                     TComMv*       pcMvSrchRngLT,
-                                     TComMv*       pcMvSrchRngRB,
+Void TEncSearch::xPatternSearchFast( const TComDataCU* const  pcCU,
+                                     const TComPattern* const pcPatternKey,
+                                     const Pel* const         piRefY,
+                                     const Int                iRefStride,
+                                     const TComMv* const      pcMvSrchRngLT,
+                                     const TComMv* const      pcMvSrchRngRB,
                                      TComMv       &rcMv,
                                      Distortion   &ruiSAD,
-                                     const TComMv* pIntegerMv2Nx2NPred )
+                                     const TComMv* const      pIntegerMv2Nx2NPred )
 {
   assert (MD_LEFT < NUM_MV_PREDICTORS);
@@ -5410,13 +5411,19 @@
   pcCU->getMvPredAboveRight ( m_acMvPredictors[MD_ABOVE_RIGHT] );
 
-  switch ( m_iFastSearch )
-  {
-    case 1:
-      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
+  switch ( m_motionEstimationSearchMethod )
+  {
+    case MESEARCH_DIAMOND:
+      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred, false );
       break;
 
-    case 2:
+    case MESEARCH_SELECTIVE:
       xTZSearchSelective( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred );
       break;
+
+    case MESEARCH_DIAMOND_ENHANCED:
+      xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred, true );
+      break;
+
+    case MESEARCH_FULL: // shouldn't get here.
     default:
       break;
@@ -5427,20 +5434,36 @@
 
 
-Void TEncSearch::xTZSearch( TComDataCU*  pcCU,
-                            TComPattern* pcPatternKey,
-                            Pel*         piRefY,
-                            Int          iRefStride,
-                            TComMv*      pcMvSrchRngLT,
-                            TComMv*      pcMvSrchRngRB,
+Void TEncSearch::xTZSearch( const TComDataCU* const pcCU,
+                            const TComPattern* const pcPatternKey,
+                            const Pel* const         piRefY,
+                            const Int                iRefStride,
+                            const TComMv* const      pcMvSrchRngLT,
+                            const TComMv* const      pcMvSrchRngRB,
                             TComMv      &rcMv,
                             Distortion  &ruiSAD,
-                            const TComMv* pIntegerMv2Nx2NPred )
+                            const TComMv* const      pIntegerMv2Nx2NPred,
+                            const Bool               bExtendedSettings)
 {
-  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
-  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
-  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
-  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
-
-  TZ_SEARCH_CONFIGURATION
+  const Bool bUseAdaptiveRaster                      = bExtendedSettings;
+  const Int  iRaster                                 = 5;
+  const Bool bTestOtherPredictedMV                   = bExtendedSettings;
+  const Bool bTestZeroVector                         = true;
+  const Bool bTestZeroVectorStart                    = bExtendedSettings;
+  const Bool bTestZeroVectorStop                     = false;
+  const Bool bFirstSearchDiamond                     = true;  // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
+  const Bool bFirstCornersForDiamondDist1            = bExtendedSettings;
+  const Bool bFirstSearchStop                        = m_pcEncCfg->getFastMEAssumingSmootherMVEnabled();
+  const UInt uiFirstSearchRounds                     = 3;     // first search stop X rounds after best match (must be >=1)
+  const Bool bEnableRasterSearch                     = true;
+  const Bool bAlwaysRasterSearch                     = bExtendedSettings;  // true: BETTER but factor 2 slower
+  const Bool bRasterRefinementEnable                 = false; // enable either raster refinement or star refinement
+  const Bool bRasterRefinementDiamond                = false; // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
+  const Bool bRasterRefinementCornersForDiamondDist1 = bExtendedSettings;
+  const Bool bStarRefinementEnable                   = true;  // enable either star refinement or raster refinement
+  const Bool bStarRefinementDiamond                  = true;  // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
+  const Bool bStarRefinementCornersForDiamondDist1   = bExtendedSettings;
+  const Bool bStarRefinementStop                     = false;
+  const UInt uiStarRefinementRounds                  = 2;  // star refinement stop X rounds after best match (must be >=1)
+  const Bool bNewZeroNeighbourhoodTest               = bExtendedSettings;
 
   UInt uiSearchRange = m_iSearchRange;
@@ -5449,5 +5472,10 @@
   if( ! pcCU->getSlice()->getIsDepth() )
 #endif
+#if ME_ENABLE_ROUNDING_OF_MVS
+  rcMv.divideByPowerOf2(2);
+#else
   rcMv >>= 2;
+#endif
+
   // init TZSearchStruct
   IntTZSearchStruct cStruct;
@@ -5470,11 +5498,19 @@
       {      
 #endif
-        cMv >>= 2;
+#if ME_ENABLE_ROUNDING_OF_MVS
+      cMv.divideByPowerOf2(2);
+#else
+      cMv >>= 2;
+#endif
+
 #if NH_3D_INTEGER_MV_DEPTH
       }
 #endif
-
+      if (cMv != rcMv && (cMv.getHor() != cStruct.iBestX && cMv.getVer() != cStruct.iBestY))
+      {
+        // only test cMV if not obviously previously tested.
       xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
     }
+  }
   }
 
@@ -5482,6 +5518,16 @@
   if ( bTestZeroVector )
   {
+    if ((rcMv.getHor() != 0 || rcMv.getVer() != 0) &&
+        (0 != cStruct.iBestX || 0 != cStruct.iBestY))
+    {
+      // only test 0-vector if not obviously previously tested.
     xTZSearchHelp( pcPatternKey, cStruct, 0, 0, 0, 0 );
   }
+  }
+
+  Int   iSrchRngHorLeft   = pcMvSrchRngLT->getHor();
+  Int   iSrchRngHorRight  = pcMvSrchRngRB->getHor();
+  Int   iSrchRngVerTop    = pcMvSrchRngLT->getVer();
+  Int   iSrchRngVerBottom = pcMvSrchRngRB->getVer();
 
   if (pIntegerMv2Nx2NPred != 0)
@@ -5490,6 +5536,15 @@
     integerMv2Nx2NPred <<= 2;
     pcCU->clipMv( integerMv2Nx2NPred );
+#if ME_ENABLE_ROUNDING_OF_MVS
+    integerMv2Nx2NPred.divideByPowerOf2(2);
+#else
     integerMv2Nx2NPred >>= 2;
+#endif
+    if ((rcMv != integerMv2Nx2NPred) &&
+        (integerMv2Nx2NPred.getHor() != cStruct.iBestX || integerMv2Nx2NPred.getVer() != cStruct.iBestY))
+    {
+      // only test integerMv2Nx2NPred if not obviously previously tested.
     xTZSearchHelp(pcPatternKey, cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
+    }
 
     // reset search range
@@ -5511,10 +5566,13 @@
   Int  iStartY = cStruct.iBestY;
 
-  // first search
+  const Bool bBestCandidateZero = (cStruct.iBestX == 0) && (cStruct.iBestY == 0);
+
+  // first search around best position up to now.
+  // The following works as a "subsampled/log" window search around the best candidate
   for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
   {
     if ( bFirstSearchDiamond == 1 )
     {
-      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
+      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, bFirstCornersForDiamondDist1 );
     }
     else
@@ -5529,4 +5587,6 @@
   }
 
+  if (!bNewZeroNeighbourhoodTest)
+  {
   // test whether zero Mv is a better start point than Median predictor
   if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) )
@@ -5538,6 +5598,25 @@
       for ( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
       {
-        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist );
+          xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist, false );
         if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion
+        {
+          break;
+        }
+      }
+    }
+  }
+  }
+  else
+  {
+    // Test also zero neighbourhood but with half the range
+    // It was reported that the original (above) search scheme using bTestZeroVectorStart did not
+    // make sense since one would have already checked the zero candidate earlier
+    // and thus the conditions for that test would have not been satisfied
+    if (bTestZeroVectorStart == true && bBestCandidateZero != true)
+    {
+      for ( iDist = 1; iDist <= ((Int)uiSearchRange >> 1); iDist*=2 )
+      {
+        xTZ8PointDiamondSearch( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, 0, 0, iDist, false );
+        if ( bTestZeroVectorStop && (cStruct.uiBestRound > 2) ) // stop criterion
         {
           break;
@@ -5555,4 +5634,31 @@
 
   // raster search if distance is too big
+  if (bUseAdaptiveRaster)
+  {
+    int iWindowSize = iRaster;
+    Int   iSrchRngRasterLeft   = iSrchRngHorLeft;
+    Int   iSrchRngRasterRight  = iSrchRngHorRight;
+    Int   iSrchRngRasterTop    = iSrchRngVerTop;
+    Int   iSrchRngRasterBottom = iSrchRngVerBottom;
+
+    if (!(bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster))))
+    {
+      iWindowSize ++;
+      iSrchRngRasterLeft /= 2;
+      iSrchRngRasterRight /= 2;
+      iSrchRngRasterTop /= 2;
+      iSrchRngRasterBottom /= 2;
+    }
+    cStruct.uiBestDistance = iWindowSize;
+    for ( iStartY = iSrchRngRasterTop; iStartY <= iSrchRngRasterBottom; iStartY += iWindowSize )
+    {
+      for ( iStartX = iSrchRngRasterLeft; iStartX <= iSrchRngRasterRight; iStartX += iWindowSize )
+      {
+        xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, iWindowSize );
+      }
+    }
+  }
+  else
+  {
   if ( bEnableRasterSearch && ( ((Int)(cStruct.uiBestDistance) > iRaster) || bAlwaysRasterSearch ) )
   {
@@ -5565,4 +5671,5 @@
       }
     }
+  }
   }
 
@@ -5579,5 +5686,5 @@
         if ( bRasterRefinementDiamond == 1 )
         {
-          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
+          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, bRasterRefinementCornersForDiamondDist1 );
         }
         else
@@ -5599,5 +5706,5 @@
   }
 
-  // start refinement
+  // star refinement
   if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 )
   {
@@ -5612,5 +5719,5 @@
         if ( bStarRefinementDiamond == 1 )
         {
-          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
+          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, bStarRefinementCornersForDiamondDist1 );
         }
         else
@@ -5638,19 +5745,30 @@
   // write out best match
   rcMv.set( cStruct.iBestX, cStruct.iBestY );
-  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
+  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY );
 }
 
 
-Void TEncSearch::xTZSearchSelective( TComDataCU*   pcCU,
-                                     TComPattern*  pcPatternKey,
-                                     Pel*          piRefY,
-                                     Int           iRefStride,
-                                     TComMv*       pcMvSrchRngLT,
-                                     TComMv*       pcMvSrchRngRB,
+Void TEncSearch::xTZSearchSelective( const TComDataCU* const   pcCU,
+                                     const TComPattern* const  pcPatternKey,
+                                     const Pel* const          piRefY,
+                                     const Int                 iRefStride,
+                                     const TComMv* const       pcMvSrchRngLT,
+                                     const TComMv* const       pcMvSrchRngRB,
                                      TComMv       &rcMv,
                                      Distortion   &ruiSAD,
-                                     const TComMv* pIntegerMv2Nx2NPred )
+                                     const TComMv* const       pIntegerMv2Nx2NPred )
 {
-  SEL_SEARCH_CONFIGURATION
+  const Bool bTestOtherPredictedMV    = true;
+  const Bool bTestZeroVector          = true;
+  const Bool bEnableRasterSearch      = true;
+  const Bool bAlwaysRasterSearch      = false;  // 1: BETTER but factor 15x slower
+  const Bool bStarRefinementEnable    = true;   // enable either star refinement or raster refinement
+  const Bool bStarRefinementDiamond   = true;   // 1 = xTZ8PointDiamondSearch   0 = xTZ8PointSquareSearch
+  const Bool bStarRefinementStop      = false;
+  const UInt uiStarRefinementRounds   = 2;  // star refinement stop X rounds after best match (must be >=1)
+  const UInt uiSearchRange            = m_iSearchRange;
+  const Int  uiSearchRangeInitial     = m_iSearchRange >> 2;
+  const Int  uiSearchStep             = 4;
+  const Int  iMVDistThresh            = 8;
 
   Int   iSrchRngHorLeft         = pcMvSrchRngLT->getHor();
@@ -5669,5 +5787,9 @@
 
   pcCU->clipMv( rcMv );
+#if ME_ENABLE_ROUNDING_OF_MVS
+  rcMv.divideByPowerOf2(2);
+#else
   rcMv >>= 2;
+#endif
   // init TZSearchStruct
   IntTZSearchStruct cStruct;
@@ -5689,5 +5811,9 @@
       TComMv cMv = m_acMvPredictors[index];
       pcCU->clipMv( cMv );
+#if ME_ENABLE_ROUNDING_OF_MVS
+      cMv.divideByPowerOf2(2);
+#else
       cMv >>= 2;
+#endif
       xTZSearchHelp( pcPatternKey, cStruct, cMv.getHor(), cMv.getVer(), 0, 0 );
     }
@@ -5705,5 +5831,9 @@
     integerMv2Nx2NPred <<= 2;
     pcCU->clipMv( integerMv2Nx2NPred );
+#if ME_ENABLE_ROUNDING_OF_MVS
+    integerMv2Nx2NPred.divideByPowerOf2(2);
+#else
     integerMv2Nx2NPred >>= 2;
+#endif
     xTZSearchHelp(pcPatternKey, cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0);
 
@@ -5734,6 +5864,6 @@
     {
       xTZSearchHelp( pcPatternKey, cStruct, iStartX, iStartY, 0, 0 );
-      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 1 );
-      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 2 );
+      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 1, false );
+      xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, 2, false );
     }
   }
@@ -5766,5 +5896,5 @@
         if ( bStarRefinementDiamond == 1 )
         {
-          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist );
+          xTZ8PointDiamondSearch ( pcPatternKey, cStruct, pcMvSrchRngLT, pcMvSrchRngRB, iStartX, iStartY, iDist, false );
         }
         else
@@ -5792,5 +5922,5 @@
   // write out best match
   rcMv.set( cStruct.iBestX, cStruct.iBestY );
-  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCost( cStruct.iBestX, cStruct.iBestY );
+  ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY );
 
 }
@@ -6027,5 +6157,5 @@
       const ComponentID component = ComponentID(comp);
       ::memset( pcCU->getCbf( component ) , 0, uiQPartNum * sizeof(UChar) );
-      ::memset( pcCU->getCrossComponentPredictionAlpha(component), 0, ( uiQPartNum * sizeof(Char) ) );
+      ::memset( pcCU->getCrossComponentPredictionAlpha(component), 0, ( uiQPartNum * sizeof(SChar) ) );
     }
     static const UInt useTS[MAX_NUM_COMPONENT]={0,0,0};
@@ -6315,5 +6445,5 @@
   //  Stores the best explicit RDPCM mode for a TU encoded without split
   UInt       bestExplicitRdpcmModeUnSplit[MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{3,3}, {3,3}, {3,3}};
-  Char       bestCrossCPredictionAlpha   [MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{0,0},{0,0},{0,0}};
+  SChar      bestCrossCPredictionAlpha   [MAX_NUM_COMPONENT][2/*0 = top (or whole TU for non-4:2:2) sub-TU, 1 = bottom sub-TU*/] = {{0,0},{0,0},{0,0}};
 
   m_pcRDGoOnSbacCoder->store( m_pppcRDSbacCoder[ uiDepth ][ CI_QT_TRAFO_ROOT ] );
@@ -6386,5 +6516,5 @@
                                                          && (pcCU->getCbf(subTUAbsPartIdx, COMPONENT_Y, uiTrMode) != 0);
 
-          Char preCalcAlpha = 0;
+          SChar preCalcAlpha = 0;
           const Pel *pLumaResi = m_pcQTTempTComYuv[uiQTTempAccessLayer].getAddrPix( COMPONENT_Y, rTu.getRect( COMPONENT_Y ).x0, rTu.getRect( COMPONENT_Y ).y0 );
 
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSearch.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSearch.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSearch.h	(revision 1360)
@@ -68,8 +68,6 @@
 private:
   TCoeff**        m_ppcQTTempCoeff[MAX_NUM_COMPONENT /* 0->Y, 1->Cb, 2->Cr*/];
-  TCoeff*         m_pcQTTempCoeff[MAX_NUM_COMPONENT];
 #if ADAPTIVE_QP_SELECTION
   TCoeff**        m_ppcQTTempArlCoeff[MAX_NUM_COMPONENT];
-  TCoeff*         m_pcQTTempArlCoeff[MAX_NUM_COMPONENT];
 #endif
   UChar*          m_puhQTTempTrIdx;
@@ -79,5 +77,5 @@
   TComYuv         m_tmpYuvPred; // To be used in xGetInterPredictionError() to avoid constant memory allocation/deallocation
 
-  Char*           m_phQTTempCrossComponentPredictionAlpha[MAX_NUM_COMPONENT];
+  SChar*          m_phQTTempCrossComponentPredictionAlpha[MAX_NUM_COMPONENT];
   Pel*            m_pSharedPredTransformSkip[MAX_NUM_COMPONENT];
   TCoeff*         m_pcQTTempTUCoeff[MAX_NUM_COMPONENT];
@@ -100,11 +98,9 @@
   Int             m_iSearchRange;
   Int             m_bipredSearchRange; // Search range for bi-prediction
-  Int             m_iFastSearch;
+  MESearchMethod  m_motionEstimationSearchMethod;
 #if NH_MV
   Bool            m_vertRestriction; 
 #endif 
   Int             m_aaiAdaptSR[MAX_NUM_REF_LIST_ADAPT_SR][MAX_IDX_ADAPT_SR];
-  TComMv          m_cSrchRngLT;
-  TComMv          m_cSrchRngRB;
   TComMv          m_acMvPredictors[NUM_MV_PREDICTORS]; // Left, Above, AboveRight. enum MVP_DIR first NUM_MV_PREDICTORS entries are suitable for accessing.
 
@@ -116,5 +112,4 @@
   // Misc.
   Pel*            m_pTempPel;
-  const UInt*     m_puiDFilter;
 
 #if NH_3D_VSO // M17
@@ -136,5 +131,5 @@
             Int           iSearchRange,
             Int           bipredSearchRange,
-            Int           iFastSearch,
+            MESearchMethod motionEstimationSearchMethod,
             const UInt    maxCUWidth,
             const UInt    maxCUHeight,
@@ -157,5 +152,5 @@
   typedef struct
   {
-    Pel*        piRefY;
+    const Pel*  piRefY;
     Int         iYStride;
     Int         iBestX;
@@ -168,8 +163,8 @@
 
   // sub-functions for ME
-  __inline Void xTZSearchHelp         ( TComPattern* pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance );
-  __inline Void xTZ2PointSearch       ( TComPattern* pcPatternKey, IntTZSearchStruct& rcStrukt, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB );
-  __inline Void xTZ8PointSquareSearch ( TComPattern* pcPatternKey, IntTZSearchStruct& rcStrukt, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist );
-  __inline Void xTZ8PointDiamondSearch( TComPattern* pcPatternKey, IntTZSearchStruct& rcStrukt, TComMv* pcMvSrchRngLT, TComMv* pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist );
+  __inline Void xTZSearchHelp         ( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const Int iSearchX, const Int iSearchY, const UChar ucPointNr, const UInt uiDistance );
+  __inline Void xTZ2PointSearch       ( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const TComMv* const pcMvSrchRngLT, const TComMv* const pcMvSrchRngRB );
+  __inline Void xTZ8PointSquareSearch ( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const TComMv* const pcMvSrchRngLT, const TComMv* const pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist );
+  __inline Void xTZ8PointDiamondSearch( const TComPattern* const pcPatternKey, IntTZSearchStruct& rcStruct, const TComMv* const pcMvSrchRngLT, const TComMv* const pcMvSrchRngRB, const Int iStartX, const Int iStartY, const Int iDist, const Bool bCheckCornersAtDist1 );
 
   Void xGetInterPredictionError( TComDataCU* pcCU, TComYuv* pcYuvOrg, Int iPartIdx, Distortion& ruiSAD, Bool Hadamard );
@@ -322,5 +317,5 @@
                                                const Int     strideBest );
 
-  Char xCalcCrossComponentPredictionAlpha    (       TComTU &rTu,
+  SChar xCalcCrossComponentPredictionAlpha   (       TComTU &rTu,
                                                const ComponentID compID,
                                                const Pel*        piResiL,
@@ -446,48 +441,49 @@
                                     Bool         bBi = false  );
 
-  Void xTZSearch                  ( TComDataCU*  pcCU,
-                                    TComPattern* pcPatternKey,
-                                    Pel*         piRefY,
-                                    Int          iRefStride,
-                                    TComMv*      pcMvSrchRngLT,
-                                    TComMv*      pcMvSrchRngRB,
+  Void xTZSearch                  ( const TComDataCU* const  pcCU,
+                                    const TComPattern* const pcPatternKey,
+                                    const Pel* const         piRefY,
+                                    const Int                iRefStride,
+                                    const TComMv* const      pcMvSrchRngLT,
+                                    const TComMv* const      pcMvSrchRngRB,
                                     TComMv&      rcMv,
                                     Distortion&  ruiSAD,
-                                    const TComMv *pIntegerMv2Nx2NPred
+                                    const TComMv* const      pIntegerMv2Nx2NPred,
+                                    const Bool               bExtendedSettings
                                     );
 
-  Void xTZSearchSelective         ( TComDataCU*  pcCU,
-                                    TComPattern* pcPatternKey,
-                                    Pel*         piRefY,
-                                    Int          iRefStride,
-                                    TComMv*      pcMvSrchRngLT,
-                                    TComMv*      pcMvSrchRngRB,
+  Void xTZSearchSelective         ( const TComDataCU* const  pcCU,
+                                    const TComPattern* const pcPatternKey,
+                                    const Pel* const         piRefY,
+                                    const Int                iRefStride,
+                                    const TComMv* const      pcMvSrchRngLT,
+                                    const TComMv* const      pcMvSrchRngRB,
                                     TComMv&      rcMv,
                                     Distortion&  ruiSAD,
-                                    const TComMv *pIntegerMv2Nx2NPred
+                                    const TComMv* const      pIntegerMv2Nx2NPred
                                     );
 
-  Void xSetSearchRange            ( TComDataCU*  pcCU,
-                                    TComMv&      cMvPred,
-                                    Int          iSrchRng,
+  Void xSetSearchRange            ( const TComDataCU* const pcCU,
+                                    const TComMv&      cMvPred,
+                                    const Int          iSrchRng,
                                     TComMv&      rcMvSrchRngLT,
                                     TComMv&      rcMvSrchRngRB );
 
-  Void xPatternSearchFast         ( TComDataCU*  pcCU,
-                                    TComPattern* pcPatternKey,
-                                    Pel*         piRefY,
-                                    Int          iRefStride,
-                                    TComMv*      pcMvSrchRngLT,
-                                    TComMv*      pcMvSrchRngRB,
+  Void xPatternSearchFast         ( const TComDataCU* const  pcCU,
+                                    const TComPattern* const pcPatternKey,
+                                    const Pel* const         piRefY,
+                                    const Int                iRefStride,
+                                    const TComMv* const      pcMvSrchRngLT,
+                                    const TComMv* const      pcMvSrchRngRB,
                                     TComMv&      rcMv,
                                     Distortion&  ruiSAD,
-                                    const TComMv* pIntegerMv2Nx2NPred
+                                    const TComMv* const      pIntegerMv2Nx2NPred
                                   );
 
-  Void xPatternSearch             ( TComPattern* pcPatternKey,
-                                    Pel*         piRefY,
-                                    Int          iRefStride,
-                                    TComMv*      pcMvSrchRngLT,
-                                    TComMv*      pcMvSrchRngRB,
+  Void xPatternSearch             ( const TComPattern* const pcPatternKey,
+                                    const Pel*               piRefY,
+                                    const Int                iRefStride,
+                                    const TComMv* const      pcMvSrchRngLT,
+                                    const TComMv* const      pcMvSrchRngRB,
                                     TComMv&      rcMv,
                                     Distortion&  ruiSAD );
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 1360)
@@ -203,5 +203,5 @@
 Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, Int layerId, bool isField )
 #else
-Void TEncSlice::initEncSlice( TComPic* pcPic, Int pocLast, Int pocCurr, Int iGOPid, TComSlice*& rpcSlice, Bool isField )
+Void TEncSlice::initEncSlice( TComPic* pcPic, const Int pocLast, const Int pocCurr, const Int iGOPid, TComSlice*& rpcSlice, const Bool isField )
 #endif
 {
@@ -397,5 +397,14 @@
 #endif
     {
-      dQPFactor=0.57*dLambda_scale;
+      if (m_pcCfg->getIntraQpFactor()>=0.0 && m_pcCfg->getGOPEntry(iGOPid).m_sliceType != I_SLICE)
+      {
+        dQPFactor=m_pcCfg->getIntraQpFactor();
+      }
+      else
+      {
+        Double dLambda_scale = 1.0 - Clip3( 0.0, 0.5, 0.05*(Double)(isField ? NumberBFrames/2 : NumberBFrames) );
+        
+        dQPFactor=0.57*dLambda_scale;
+      }
     }
     dLambda = dQPFactor*pow( 2.0, qp_temp/3.0 );
@@ -428,13 +437,23 @@
   iQP     = m_piRdPicQp    [0];
 
-  if( rpcSlice->getSliceType( ) != I_SLICE )
-  {
+
 #if NH_MV
-    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId );
-#else
-    dLambda *= m_pcCfg->getLambdaModifier( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
-#endif
-  }
-
+  const Int temporalId=m_pcCfg->getGOPEntry((eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid).m_temporalId;
+#else
+  const Int temporalId=m_pcCfg->getGOPEntry(iGOPid).m_temporalId;
+#endif
+  const std::vector<Double> &intraLambdaModifiers=m_pcCfg->getIntraLambdaModifier();
+
+  Double lambdaModifier;
+  if( rpcSlice->getSliceType( ) != I_SLICE || intraLambdaModifiers.empty())
+  {
+    lambdaModifier = m_pcCfg->getLambdaModifier( temporalId );
+  }
+  else
+  {
+    lambdaModifier = intraLambdaModifiers[ (temporalId < intraLambdaModifiers.size()) ? temporalId : (intraLambdaModifiers.size()-1) ];
+  }
+
+  dLambda *= lambdaModifier;
   setUpLambda(rpcSlice, dLambda, iQP);
 
@@ -547,9 +566,5 @@
   rpcSlice->setDepth            ( depth );
 
-#if NH_MV
-  pcPic->setTLayer( m_pcCfg->getGOPEntry( (eSliceTypeBaseView == I_SLICE) ? MAX_GOP : iGOPid ).m_temporalId );
-#else
-  pcPic->setTLayer( m_pcCfg->getGOPEntry(iGOPid).m_temporalId );
-#endif
+  pcPic->setTLayer( temporalId );
   if(eSliceType==I_SLICE)
   {
@@ -589,4 +604,5 @@
 // ====================================================================================================================
 
+//! set adaptive search range based on poc difference
 Void TEncSlice::setSearchRange( TComSlice* pcSlice )
 {
@@ -598,13 +614,12 @@
   Int iNumPredDir = pcSlice->isInterP() ? 1 : 2;
 
-  for (Int iDir = 0; iDir <= iNumPredDir; iDir++)
-  {
-    //RefPicList e = (RefPicList)iDir;
+  for (Int iDir = 0; iDir < iNumPredDir; iDir++)
+  {
     RefPicList  e = ( iDir ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
     for (Int iRefIdx = 0; iRefIdx < pcSlice->getNumRefIdx(e); iRefIdx++)
     {
       iRefPOC = pcSlice->getRefPic(e, iRefIdx)->getPOC();
-      Int iNewSR = Clip3(8, iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
-      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, iNewSR);
+      Int newSearchRange = Clip3(m_pcCfg->getMinSearchWindow(), iMaxSR, (iMaxSR*ADAPT_SR_SCALE*abs(iCurrPOC - iRefPOC)+iOffset)/iGOPSize);
+      m_pcPredSearch->setAdaptiveSearchRange(iDir, iRefIdx, newSearchRange);
     }
   }
@@ -696,5 +711,9 @@
 
     // compute RD cost and choose the best
-    Double dPicRdCost = m_pcRdCost->calcRdCost64( m_uiPicTotalBits, uiPicDist, true, DF_SSE_FRAME); // NOTE: Is the 'true' parameter really necessary?
+#if NH_3D
+    Double dPicRdCost = m_pcRdCost->calcRdCost( (Double)m_uiPicTotalBits, uiPicDist, DF_SSE_FRAME);
+#else
+    Double dPicRdCost = m_pcRdCost->calcRdCost( (Double)m_uiPicTotalBits, (Double)uiPicDist, DF_SSE_FRAME);
+#endif
 #if H_3D
     // Above calculation need to be fixed for VSO, including frameLambda value. 
@@ -805,5 +824,5 @@
     }
 
-    xEstimateWPParamSlice( pcSlice );
+    xEstimateWPParamSlice( pcSlice, m_pcCfg->getWeightedPredictionMethod() );
     pcSlice->initWpScaling(pcSlice->getSPS());
 
@@ -849,5 +868,5 @@
     {
       // This will only occur if dependent slice-segments (m_entropyCodingSyncContextState=true) are being used.
-      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getWaveFrontsynchro() )
+      if( pCurrentTile->getTileWidthInCtus() >= 2 || !m_pcCfg->getEntropyCodingSyncEnabledFlag() )
       {
         m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( &m_lastSliceSegmentEndContextState );
@@ -892,5 +911,5 @@
       m_pppcRDSbacCoder[0][CI_CURR_BEST]->resetEntropy(pcSlice);
     }
-    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getWaveFrontsynchro())
+    else if ( ctuXPosInCtus == tileXPosInCtus && m_pcCfg->getEntropyCodingSyncEnabledFlag())
     {
       // reset and then update contexts to the state at the end of the top-right CTU (if within current slice and tile).
@@ -1031,5 +1050,5 @@
 
     // Store probabilities of second CTU in line into buffer - used only if wavefront-parallel-processing is enabled.
-    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getWaveFrontsynchro())
+    if ( ctuXPosInCtus == tileXPosInCtus+1 && m_pcCfg->getEntropyCodingSyncEnabledFlag())
     {
       m_entropyCodingSyncContextState.loadContexts(m_pppcRDSbacCoder[0][CI_CURR_BEST]);
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSlice.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSlice.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncSlice.h	(revision 1360)
@@ -120,6 +120,6 @@
                                 Int iGOPid, TComSlice*& rpcSlice, TComVPS* pVPS, Int layerId, bool isField  ); 
 #else
-  Void    initEncSlice        ( TComPic*  pcPic, Int pocLast, Int pocCurr, 
-                                Int iGOPid,   TComSlice*& rpcSlice, Bool isField );
+  Void    initEncSlice        ( TComPic*  pcPic, const Int pocLast, const Int pocCurr,
+                                const Int iGOPid,   TComSlice*& rpcSlice, const Bool isField );
 #endif
   Void    resetQP             ( TComPic* pic, Int sliceQP, Double lambda );
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncTop.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/TEncTop.cpp	(revision 1360)
@@ -44,5 +44,5 @@
 #endif
 #if NH_MV
-#include "../../App/TAppEncoder/TAppEncTop.h"
+//#include "../../App/TAppEncoder/TAppEncTop.h"
 #endif
 
@@ -216,4 +216,10 @@
   xInitVPS();
 
+#if U0132_TARGET_BITS_SATURATION
+  if (m_RCCpbSaturationEnabled)
+  {
+    m_cRateCtrl.initHrdParam(m_cSPS.getVuiParameters()->getHrdParameters(), m_iFrameRate, m_RCInitialCpbFullness);
+  }
+#endif
   m_cRdCost.setCostMode(m_costMode);
 
@@ -264,5 +270,5 @@
 
   // initialize encoder search class
-  m_cSearch.init( this, &m_cTrQuant, m_iSearchRange, m_bipredSearchRange, m_iFastSearch, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, &m_cEntropyCoder, &m_cRdCost, getRDSbacCoder(), getRDGoOnSbacCoder() );
+  m_cSearch.init( this, &m_cTrQuant, m_iSearchRange, m_bipredSearchRange, m_motionEstimationSearchMethod, m_maxCUWidth, m_maxCUHeight, m_maxTotalCUDepth, &m_cEntropyCoder, &m_cRdCost, getRDSbacCoder(), getRDGoOnSbacCoder() );
 
   m_iMaxRefPicNum = 0;
@@ -299,5 +305,5 @@
   {
     m_cSPS.getScalingList().setDefaultScalingList ();
-    if(m_cSPS.getScalingList().xParseScalingList(getScalingListFile()))
+    if(m_cSPS.getScalingList().xParseScalingList(getScalingListFileName()))
     {
       Bool bParsedScalingList=false; // Use of boolean so that assertion outputs useful string
@@ -842,5 +848,10 @@
     m_cSPS.setUsedByCurrPicLtSPSFlag(k, 0);
   }
+
+#if U0132_TARGET_BITS_SATURATION
+  if( getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() || getCpbSaturationEnabled() )
+#else
   if( getPictureTimingSEIEnabled() || getDecodingUnitInfoSEIEnabled() )
+#endif
   {
     xInitHrdParameters();
@@ -866,7 +877,21 @@
   m_cSPS.setSpsRangeExtensionsFlag( m_cSPS.getSpsRangeExtension().settingsDifferFromDefaults() );
 #endif
-
-}
-
+}
+#if U0132_TARGET_BITS_SATURATION
+// calculate scale value of bitrate and initial delay
+Int calcScale(Int x)
+{
+  UInt iMask = 0xffffffff;
+  Int ScaleValue = 32;
+
+  while ((x&iMask) != 0)
+  {
+    ScaleValue--;
+    iMask = (iMask >> 1);
+}
+
+  return ScaleValue;
+}
+#endif
 Void TEncTop::xInitHrdParameters()
 {
@@ -874,6 +899,11 @@
   Int  bitRate         = getTargetBitrate();
   Bool isRandomAccess  = getIntraPeriod() > 0;
-
+# if U0132_TARGET_BITS_SATURATION
+  Int cpbSize          = getCpbSize();
+
+  if( !getVuiParametersPresentFlag() && !getCpbSaturationEnabled() )
+#else
   if( !getVuiParametersPresentFlag() )
+#endif
   {
     return;
@@ -925,6 +955,27 @@
   }
 
+#if U0132_TARGET_BITS_SATURATION
+  if (calcScale(bitRate) <= 6)
+  {
+    hrd->setBitRateScale(0);
+  }
+  else
+  {
+    hrd->setBitRateScale(calcScale(bitRate) - 6);
+  }
+
+  if (calcScale(cpbSize) <= 4)
+  {
+    hrd->setCpbSizeScale(0);
+  }
+  else
+  {
+    hrd->setCpbSizeScale(calcScale(cpbSize) - 4);
+  }
+#else
   hrd->setBitRateScale( 4 );                                       // in units of 2^( 6 + 4 ) = 1,024 bps
   hrd->setCpbSizeScale( 6 );                                       // in units of 2^( 4 + 6 ) = 1,024 bit
+#endif
+
   hrd->setDuCpbSizeScale( 6 );                                     // in units of 2^( 4 + 6 ) = 1,024 bit
 
@@ -958,5 +1009,10 @@
     bitrateValue = bitRate / (1 << (6 + hrd->getBitRateScale()) );      // bitRate is in bits, so it needs to be scaled down
     // CpbSize[ i ] = ( cpb_size_value_minus1[ i ] + 1 ) * 2^( 4 + cpb_size_scale )
+#if U0132_TARGET_BITS_SATURATION
+    cpbSizeValue = cpbSize / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
+#else
     cpbSizeValue = bitRate / (1 << (4 + hrd->getCpbSizeScale()) );      // using bitRate results in 1 second CPB size
+#endif
+
 
     // DU CPB size could be smaller (i.e. bitrateValue / number of DUs), but we don't know 
@@ -1066,5 +1122,5 @@
   m_cPPS.setQpOffset(COMPONENT_Cr, m_chromaCrQpOffset );
 
-  m_cPPS.setEntropyCodingSyncEnabledFlag( m_iWaveFrontSynchro > 0 );
+  m_cPPS.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag );
   m_cPPS.setTilesEnabledFlag( (m_iNumColumnsMinus1 > 0 || m_iNumRowsMinus1 > 0) );
   m_cPPS.setUseWP( m_useWeightedPred );
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/WeightPredAnalysis.cpp
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/WeightPredAnalysis.cpp	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/WeightPredAnalysis.cpp	(revision 1360)
@@ -41,7 +41,186 @@
 #include "../TLibCommon/TComPicYuv.h"
 #include "WeightPredAnalysis.h"
-
-#define ABS(a)    ((a) < 0 ? - (a) : (a))
-#define DTHRESH (0.99)
+#include <limits>
+
+static const Double WEIGHT_PRED_SAD_RELATIVE_TO_NON_WEIGHT_PRED_SAD=0.99; // NOTE: U0040 used 0.95
+
+//! calculate SAD values for both WP version and non-WP version.
+static
+Int64 xCalcSADvalueWP(const Int   bitDepth,
+                      const Pel  *pOrgPel,
+                      const Pel  *pRefPel,
+                      const Int   width,
+                      const Int   height,
+                      const Int   orgStride,
+                      const Int   refStride,
+                      const Int   log2Denom,
+                      const Int   weight,
+                      const Int   offset,
+                      const Bool  useHighPrecision);
+
+//! calculate SAD values for both WP version and non-WP version.
+static
+Int64 xCalcSADvalueWPOptionalClip(const Int   bitDepth,
+                                  const Pel  *pOrgPel,
+                                  const Pel  *pRefPel,
+                                  const Int   width,
+                                  const Int   height,
+                                  const Int   orgStride,
+                                  const Int   refStride,
+                                  const Int   log2Denom,
+                                  const Int   weight,
+                                  const Int   offset,
+                                  const Bool  useHighPrecision,
+                                  const Bool  clipped);
+
+// -----------------------------------------------------------------------------
+// Helper functions
+
+
+//! calculate Histogram for array of pixels
+static
+Void xCalcHistogram(const Pel  *pPel,
+                    std::vector<Int> &histogram,
+                    const Int   width,
+                    const Int   height,
+                    const Int   stride,
+                    const Int   maxPel)
+{
+  histogram.clear();
+  histogram.resize(maxPel);
+  for( Int y = 0; y < height; y++ )
+  {
+    for( Int x = 0; x < width; x++ )
+    {
+      const Pel v=pPel[x];
+      histogram[v<0?0:(v>=maxPel)?maxPel-1:v]++;
+    }
+    pPel += stride;
+  }
+}
+
+static
+Distortion xCalcHistDistortion (const std::vector<Int> &histogram0,
+                                const std::vector<Int> &histogram1)
+{
+  Distortion distortion = 0;
+  assert(histogram0.size()==histogram1.size());
+  const Int numElements=Int(histogram0.size());
+
+  // Scan histograms to compute histogram distortion
+  for (Int i = 0; i <= numElements; i++)
+  {
+    distortion += (Distortion)(abs(histogram0[i] - histogram1[i]));
+  }
+
+  return distortion;
+}
+
+static
+void xScaleHistogram(const std::vector<Int> &histogramInput,
+                           std::vector<Int> &histogramOutput, // cannot be the same as the input
+                     const Int               bitDepth,
+                     const Int               log2Denom,
+                     const Int               weight,
+                     const Int               offset,
+                     const Bool              bHighPrecision)
+{
+  assert(&histogramInput != &histogramOutput);
+  const Int numElements=Int(histogramInput.size());
+  histogramOutput.clear();
+  histogramOutput.resize(numElements);
+
+  const Int64 iRealLog2Denom = bHighPrecision ? 0 : (bitDepth - 8);
+  const Int64 iRealOffset    = ((Int64)offset)<<iRealLog2Denom;
+
+  const Int divOffset = log2Denom == 0 ? 0 : 1 << (log2Denom - 1);
+  // Scan histogram and apply illumination parameters appropriately
+  // Then compute updated histogram.
+  // Note that this technique only works with single list weights/offsets.
+
+  for (Int i = 0; i < numElements; i++)
+  {
+    const Int j = Clip3(0, numElements - 1, (Int)(((weight * i + divOffset) >> log2Denom) + iRealOffset));
+    histogramOutput[j] += histogramInput[i];
+  }
+}
+
+static
+Distortion xSearchHistogram(const std::vector<Int> &histogramSource,
+                            const std::vector<Int> &histogramRef,
+                                  std::vector<Int> &outputHistogram,
+                            const Int               bitDepth,
+                            const Int               log2Denom,
+                                  Int              &weightToUpdate,
+                                  Int              &offsetToUpdate,
+                            const Bool              bHighPrecision,
+                            const ComponentID       compID)
+{
+  const Int initialWeight   = weightToUpdate;
+  const Int initialOffset   = offsetToUpdate;
+  const Int weightRange     = 10;
+  const Int offsetRange     = 10;
+  const Int maxOffset       = 1 << ((bHighPrecision == true) ? (bitDepth - 1) : 7);
+  const Int range           = bHighPrecision ? (1<<bitDepth) / 2 : 128;
+  const Int defaultWeight   = (1<<log2Denom);
+  const Int minSearchWeight = std::max<Int>(initialWeight - weightRange, defaultWeight - range);
+  const Int maxSearchWeight = std::min<Int>(initialWeight + weightRange+1, defaultWeight + range);
+
+  Distortion minDistortion   = std::numeric_limits<Distortion>::max();
+  Int        bestWeight      = initialWeight;
+  Int        bestOffset      = initialOffset;
+
+  for (Int searchWeight = minSearchWeight; searchWeight < maxSearchWeight; searchWeight++)
+  {
+    if (compID == COMPONENT_Y)
+    {
+      for (Int searchOffset = std::max<Int>(initialOffset - offsetRange, -maxOffset);
+               searchOffset <= initialOffset + offsetRange && searchOffset<=(maxOffset-1);
+               searchOffset++)
+      {
+        xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, searchOffset, bHighPrecision);
+        const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram);
+
+        if (distortion < minDistortion)
+        {
+          minDistortion = distortion;
+          bestWeight    = searchWeight;
+          bestOffset    = searchOffset;
+        }
+      }
+    }
+    else
+    {
+      const Int pred        = ( maxOffset - ( ( maxOffset*searchWeight)>>(log2Denom) ) );
+
+      for (Int searchOffset = initialOffset - offsetRange; searchOffset <= initialOffset + offsetRange; searchOffset++)
+      {
+        const Int deltaOffset   = Clip3( -4*maxOffset, 4*maxOffset-1, (searchOffset - pred) ); // signed 10bit (if !bHighPrecision)
+        const Int clippedOffset = Clip3( -1*maxOffset, 1*maxOffset-1, (deltaOffset  + pred) ); // signed 8bit  (if !bHighPrecision)
+        xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, searchWeight, clippedOffset, bHighPrecision);
+        const Distortion distortion = xCalcHistDistortion(histogramSource, outputHistogram);
+
+        if (distortion < minDistortion)
+        {
+          minDistortion = distortion;
+          bestWeight    = searchWeight;
+          bestOffset    = clippedOffset;
+        }
+      }
+    }
+  }
+
+  weightToUpdate = bestWeight;
+  offsetToUpdate = bestOffset;
+
+  // regenerate best histogram
+  xScaleHistogram(histogramRef, outputHistogram, bitDepth, log2Denom, bestWeight, bestOffset, bHighPrecision);
+
+  return minDistortion;
+}
+
+
+// -----------------------------------------------------------------------------
+// Member functions
 
 WeightPredAnalysis::WeightPredAnalysis()
@@ -49,9 +228,9 @@
   for ( UInt lst =0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
   {
-    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
+    for ( Int refIdx=0 ; refIdx<MAX_NUM_REF ; refIdx++ )
     {
       for ( Int comp=0 ; comp<MAX_NUM_COMPONENT ;comp++ )
       {
-        WPScalingParam  *pwp   = &(m_wp[lst][iRefIdx][comp]);
+        WPScalingParam  *pwp   = &(m_wp[lst][refIdx][comp]);
         pwp->bPresentFlag      = false;
         pwp->uiLog2WeightDenom = 0;
@@ -78,34 +257,34 @@
     // calculate DC/AC value for channel
 
-    const Int iStride = pPic->getStride(compID);
-    const Int iWidth  = pPic->getWidth(compID);
-    const Int iHeight = pPic->getHeight(compID);
-
-    const Int iSample = iWidth*iHeight;
-
-    Int64 iOrgDC = 0;
+    const Int stride = pPic->getStride(compID);
+    const Int width  = pPic->getWidth(compID);
+    const Int height = pPic->getHeight(compID);
+
+    const Int sample = width*height;
+
+    Int64 orgDC = 0;
     {
       const Pel *pPel = pPic->getAddr(compID);
 
-      for(Int y = 0; y < iHeight; y++, pPel+=iStride )
-      {
-        for(Int x = 0; x < iWidth; x++ )
-        {
-          iOrgDC += (Int)( pPel[x] );
-        }
-      }
-    }
-
-    const Int64 iOrgNormDC = ((iOrgDC+(iSample>>1)) / iSample);
-
-    Int64 iOrgAC = 0;
+      for(Int y = 0; y < height; y++, pPel+=stride )
+      {
+        for(Int x = 0; x < width; x++ )
+        {
+          orgDC += (Int)( pPel[x] );
+        }
+      }
+    }
+
+    const Int64 orgNormDC = ((orgDC+(sample>>1)) / sample);
+
+    Int64 orgAC = 0;
     {
       const Pel *pPel = pPic->getAddr(compID);
 
-      for(Int y = 0; y < iHeight; y++, pPel += iStride )
-      {
-        for(Int x = 0; x < iWidth; x++ )
-        {
-          iOrgAC += abs( (Int)pPel[x] - (Int)iOrgNormDC );
+      for(Int y = 0; y < height; y++, pPel += stride )
+      {
+        for(Int x = 0; x < width; x++ )
+        {
+          orgAC += abs( (Int)pPel[x] - (Int)orgNormDC );
         }
       }
@@ -113,6 +292,6 @@
 
     const Int fixedBitShift = (slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag())?RExt__PREDICTION_WEIGHTING_ANALYSIS_DC_PRECISION:0;
-    weightACDCParam[compID].iDC = (((iOrgDC<<fixedBitShift)+(iSample>>1)) / iSample);
-    weightACDCParam[compID].iAC = iOrgAC;
+    weightACDCParam[compID].iDC = (((orgDC<<fixedBitShift)+(sample>>1)) / sample);
+    weightACDCParam[compID].iAC = orgAC;
   }
 
@@ -126,18 +305,18 @@
   const TComPicYuv *pPic = slice->getPic()->getPicYuvOrg();
 
-  Int iPresentCnt = 0;
+  Int presentCnt = 0;
   for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
   {
-    for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
+    for ( Int refIdx=0 ; refIdx<MAX_NUM_REF ; refIdx++ )
     {
       for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
       {
-        WPScalingParam  *pwp = &(m_wp[lst][iRefIdx][componentIndex]);
-        iPresentCnt += (Int)pwp->bPresentFlag;
-      }
-    }
-  }
-
-  if(iPresentCnt==0)
+        WPScalingParam  *pwp = &(m_wp[lst][refIdx][componentIndex]);
+        presentCnt += (Int)pwp->bPresentFlag;
+      }
+    }
+  }
+
+  if(presentCnt==0)
   {
     slice->setTestWeightPred(false);
@@ -146,9 +325,9 @@
     for ( UInt lst=0 ; lst<NUM_REF_PIC_LIST_01 ; lst++ )
     {
-      for ( Int iRefIdx=0 ; iRefIdx<MAX_NUM_REF ; iRefIdx++ )
+      for ( Int refIdx=0 ; refIdx<MAX_NUM_REF ; refIdx++ )
       {
         for(Int componentIndex = 0; componentIndex < pPic->getNumberValidComponents(); componentIndex++)
         {
-          WPScalingParam  *pwp = &(m_wp[lst][iRefIdx][componentIndex]);
+          WPScalingParam  *pwp = &(m_wp[lst][refIdx][componentIndex]);
 
           pwp->bPresentFlag      = false;
@@ -163,5 +342,5 @@
   else
   {
-    slice->setTestWeightPred(slice->getPPS()->getUseWP());
+    slice->setTestWeightPred  (slice->getPPS()->getUseWP());
     slice->setTestWeightBiPred(slice->getPPS()->getWPBiPred());
   }
@@ -170,5 +349,5 @@
 
 //! estimate wp tables for explicit wp
-Void WeightPredAnalysis::xEstimateWPParamSlice(TComSlice *const slice)
+Void WeightPredAnalysis::xEstimateWPParamSlice(TComSlice *const slice, const WeightedPredictionMethod method)
 {
   Int  iDenom         = 6;
@@ -191,5 +370,25 @@
   // selecting whether WP is used, or not (fast search)
   // NOTE: This is not operating on a slice, but the entire picture.
-  xSelectWP(slice, iDenom);
+  switch (method)
+  {
+    case WP_PER_PICTURE_WITH_SIMPLE_DC_COMBINED_COMPONENT:
+      xSelectWP(slice, iDenom);
+      break;
+    case WP_PER_PICTURE_WITH_SIMPLE_DC_PER_COMPONENT:
+      xSelectWPHistExtClip(slice, iDenom, false, false, false);
+      break;
+    case WP_PER_PICTURE_WITH_HISTOGRAM_AND_PER_COMPONENT:
+      xSelectWPHistExtClip(slice, iDenom, false, false, true);
+      break;
+    case WP_PER_PICTURE_WITH_HISTOGRAM_AND_PER_COMPONENT_AND_CLIPPING:
+      xSelectWPHistExtClip(slice, iDenom, false, true, true);
+      break;
+    case WP_PER_PICTURE_WITH_HISTOGRAM_AND_PER_COMPONENT_AND_CLIPPING_AND_EXTENSION:
+      xSelectWPHistExtClip(slice, iDenom, true, true, true);
+      break;
+    default:
+      assert(0);
+      exit(1);
+  }
 
   slice->setWpScaling( m_wp );
@@ -251,5 +450,5 @@
         // Weighting factor limitation
         const Int defaultWeight = (1<<log2Denom);
-        const Int deltaWeight   = (defaultWeight - weight);
+        const Int deltaWeight   = (weight - defaultWeight);
 
         if(deltaWeight >= range || deltaWeight < -range)
@@ -269,21 +468,143 @@
 
 
+/** select whether weighted pred enables or not.
+ * \param TComSlice *slice
+ * \param log2Denom
+ * \returns Bool
+ */
+Bool WeightPredAnalysis::xSelectWPHistExtClip(TComSlice *const slice, const Int log2Denom, const Bool bDoEnhancement, const Bool bClipInitialSADWP, const Bool bUseHistogram)
+{
+  const TComPicYuv *const pPic             = slice->getPic()->getPicYuvOrg();
+  const Int               defaultWeight    = 1<<log2Denom;
+  const Int               numPredDir       = slice->isInterP() ? 1 : 2;
+  const Bool              useHighPrecision = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
+
+  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
+
+  for ( Int refList = 0; refList < numPredDir; refList++ )
+  {
+    const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+
+    for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
+    {
+      Bool  useChromaWeight = false;
+
+      for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
+      {
+        const ComponentID  compID     = ComponentID(comp);
+        const Pel         *pOrg       = pPic->getAddr(compID);
+        const Pel         *pRef       = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getAddr(compID);
+        const Int          orgStride  = pPic->getStride(compID);
+        const Int          refStride  = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getStride(compID);
+        const Int          width      = pPic->getWidth(compID);
+        const Int          height     = pPic->getHeight(compID);
+        const Int          bitDepth   = slice->getSPS()->getBitDepth(toChannelType(compID));
+              WPScalingParam &wp      = m_wp[refList][refIdxTemp][compID];
+              Int          weight     = wp.iWeight;
+              Int          offset     = wp.iOffset;
+              Int          weightDef  = defaultWeight;
+              Int          offsetDef  = 0;
+
+        // calculate SAD costs with/without wp for luma
+        const Int64 SADnoWP = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecision, bClipInitialSADWP);
+        if (SADnoWP > 0)
+        {
+          const Int64 SADWP   = xCalcSADvalueWPOptionalClip(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight,   offset, useHighPrecision, bClipInitialSADWP);
+          const Double dRatioSAD = (Double)SADWP / (Double)SADnoWP;
+          Double dRatioSr0SAD = std::numeric_limits<Double>::max();
+          Double dRatioSrSAD  = std::numeric_limits<Double>::max();
+
+          if (bUseHistogram)
+          {
+            std::vector<Int> histogramOrg;// = pPic->getHistogram(compID);
+            std::vector<Int> histogramRef;// = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getHistogram(compID);
+            std::vector<Int> searchedHistogram;
+
+            // Compute histograms
+            xCalcHistogram(pOrg, histogramOrg, width, height, orgStride, 1 << bitDepth);
+            xCalcHistogram(pRef, histogramRef, width, height, refStride, 1 << bitDepth);
+
+            // Do a histogram search around DC WP parameters; resulting distortion and 'searchedHistogram' is discarded
+            xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weight, offset, useHighPrecision, compID);
+            // calculate updated WP SAD
+            const Int64 SADSrWP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weight, offset, useHighPrecision);
+            dRatioSrSAD  = (Double)SADSrWP  / (Double)SADnoWP;
+
+            if (bDoEnhancement)
+            {
+              // Do the same around the default ones; resulting distortion and 'searchedHistogram' is discarded
+              xSearchHistogram(histogramOrg, histogramRef, searchedHistogram, bitDepth, log2Denom, weightDef, offsetDef, useHighPrecision, compID);
+              // calculate updated WP SAD
+              const Int64 SADSr0WP = xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, weightDef, offsetDef, useHighPrecision);
+              dRatioSr0SAD = (Double)SADSr0WP / (Double)SADnoWP;
+            }
+          }
+
+          if(min(dRatioSr0SAD, min(dRatioSAD, dRatioSrSAD)) >= WEIGHT_PRED_SAD_RELATIVE_TO_NON_WEIGHT_PRED_SAD)
+          {
+            wp.bPresentFlag      = false;
+            wp.iOffset           = 0;
+            wp.iWeight           = defaultWeight;
+            wp.uiLog2WeightDenom = log2Denom;
+          }
+          else
+          {
+            if (compID != COMPONENT_Y)
+            {
+              useChromaWeight = true;
+            }
+
+            if (dRatioSr0SAD < dRatioSrSAD && dRatioSr0SAD < dRatioSAD)
+            {
+              wp.bPresentFlag      = true;
+              wp.iOffset           = offsetDef;
+              wp.iWeight           = weightDef;
+              wp.uiLog2WeightDenom = log2Denom;
+            }
+            else if (dRatioSrSAD < dRatioSAD)
+            {
+              wp.bPresentFlag      = true;
+              wp.iOffset           = offset;
+              wp.iWeight           = weight;
+              wp.uiLog2WeightDenom = log2Denom;
+            }
+          }
+        }
+        else // (SADnoWP <= 0)
+        {
+          wp.bPresentFlag      = false;
+          wp.iOffset           = 0;
+          wp.iWeight           = defaultWeight;
+          wp.uiLog2WeightDenom = log2Denom;
+        }
+      }
+
+      for(Int comp=1; comp<pPic->getNumberValidComponents(); comp++)
+      {
+        m_wp[refList][refIdxTemp][comp].bPresentFlag = useChromaWeight;
+      }
+    }
+  }
+
+  return true;
+}
+
 //! select whether weighted pred enables or not.
 Bool WeightPredAnalysis::xSelectWP(TComSlice *const slice, const Int log2Denom)
 {
         TComPicYuv *const pPic                                = slice->getPic()->getPicYuvOrg();
-  const Int               iDefaultWeight                      = ((Int)1<<log2Denom);
-  const Int               iNumPredDir                         = slice->isInterP() ? 1 : 2;
+  const Int               defaultWeight                       = 1<<log2Denom;
+  const Int               numPredDir                          = slice->isInterP() ? 1 : 2;
   const Bool              useHighPrecisionPredictionWeighting = slice->getSPS()->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
 
-  assert (iNumPredDir <= Int(NUM_REF_PIC_LIST_01));
-
-  for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )
-  {
-    const RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
-
-    for ( Int iRefIdxTemp = 0; iRefIdxTemp < slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ )
-    {
-      Int64 iSADWP = 0, iSADnoWP = 0;
+  assert (numPredDir <= Int(NUM_REF_PIC_LIST_01));
+
+  for ( Int refList = 0; refList < numPredDir; refList++ )
+  {
+    const RefPicList eRefPicList = ( refList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 );
+
+    for ( Int refIdxTemp = 0; refIdxTemp < slice->getNumRefIdx(eRefPicList); refIdxTemp++ )
+    {
+      Int64 SADWP = 0, SADnoWP = 0;
 
       for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
@@ -291,25 +612,26 @@
         const ComponentID  compID     = ComponentID(comp);
               Pel         *pOrg       = pPic->getAddr(compID);
-              Pel         *pRef       = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getAddr(compID);
-        const Int          iOrgStride = pPic->getStride(compID);
-        const Int          iRefStride = slice->getRefPic(eRefPicList, iRefIdxTemp)->getPicYuvRec()->getStride(compID);
-        const Int          iWidth     = pPic->getWidth(compID);
-        const Int          iHeight    = pPic->getHeight(compID);
+              Pel         *pRef       = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getAddr(compID);
+        const Int          orgStride = pPic->getStride(compID);
+        const Int          refStride = slice->getRefPic(eRefPicList, refIdxTemp)->getPicYuvRec()->getStride(compID);
+        const Int          width     = pPic->getWidth(compID);
+        const Int          height    = pPic->getHeight(compID);
         const Int          bitDepth   = slice->getSPS()->getBitDepth(toChannelType(compID));
 
         // calculate SAD costs with/without wp for luma
-        iSADWP   += xCalcSADvalueWP(bitDepth, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, log2Denom, m_wp[iRefList][iRefIdxTemp][compID].iWeight, m_wp[iRefList][iRefIdxTemp][compID].iOffset, useHighPrecisionPredictionWeighting);
-        iSADnoWP += xCalcSADvalueWP(bitDepth, pOrg, pRef, iWidth, iHeight, iOrgStride, iRefStride, log2Denom, iDefaultWeight, 0, useHighPrecisionPredictionWeighting);
-      }
-
-      const Double dRatio = ((Double)iSADWP / (Double)iSADnoWP);
-      if(dRatio >= (Double)DTHRESH)
+        SADWP   += xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, m_wp[refList][refIdxTemp][compID].iWeight, m_wp[refList][refIdxTemp][compID].iOffset, useHighPrecisionPredictionWeighting);
+        SADnoWP += xCalcSADvalueWP(bitDepth, pOrg, pRef, width, height, orgStride, refStride, log2Denom, defaultWeight, 0, useHighPrecisionPredictionWeighting);
+      }
+
+      const Double dRatio = SADnoWP > 0 ? (((Double)SADWP / (Double)SADnoWP)) : std::numeric_limits<Double>::max();
+      if(dRatio >= WEIGHT_PRED_SAD_RELATIVE_TO_NON_WEIGHT_PRED_SAD)
       {
         for(Int comp=0; comp<pPic->getNumberValidComponents(); comp++)
         {
-          m_wp[iRefList][iRefIdxTemp][comp].bPresentFlag      = false;
-          m_wp[iRefList][iRefIdxTemp][comp].iOffset           = 0;
-          m_wp[iRefList][iRefIdxTemp][comp].iWeight           = iDefaultWeight;
-          m_wp[iRefList][iRefIdxTemp][comp].uiLog2WeightDenom = log2Denom;
+          WPScalingParam &wp=m_wp[refList][refIdxTemp][comp];
+          wp.bPresentFlag      = false;
+          wp.iOffset           = 0;
+          wp.iWeight           = defaultWeight;
+          wp.uiLog2WeightDenom = log2Denom;
         }
       }
@@ -320,32 +642,88 @@
 }
 
-
-//! calculate SAD values for both WP version and non-WP version.
-Int64 WeightPredAnalysis::xCalcSADvalueWP(const Int   bitDepth,
-                                          const Pel  *pOrgPel,
-                                          const Pel  *pRefPel,
-                                          const Int   iWidth,
-                                          const Int   iHeight,
-                                          const Int   iOrgStride,
-                                          const Int   iRefStride,
-                                          const Int   iLog2Denom,
-                                          const Int   iWeight,
-                                          const Int   iOffset,
-                                          const Bool  useHighPrecisionPredictionWeighting)
-{
-  const Int64 iSize          = iWidth*iHeight;
-  const Int64 iRealLog2Denom = useHighPrecisionPredictionWeighting ? iLog2Denom : (iLog2Denom + (bitDepth - 8));
-
-  Int64 iSAD = 0;
-  for( Int y = 0; y < iHeight; y++ )
-  {
-    for( Int x = 0; x < iWidth; x++ )
-    {
-      iSAD += ABS(( ((Int64)pOrgPel[x]<<(Int64)iLog2Denom) - ( (Int64)pRefPel[x] * (Int64)iWeight + ((Int64)iOffset<<iRealLog2Denom) ) ) );
-    }
-    pOrgPel += iOrgStride;
-    pRefPel += iRefStride;
-  }
-
-  return (iSAD/iSize);
-}
+// Alternatively, a SSE-based measure could be used instead.
+// The respective function has been removed as it currently redundant.
+static
+Int64 xCalcSADvalueWP(const Int   bitDepth,
+                      const Pel  *pOrgPel,
+                      const Pel  *pRefPel,
+                      const Int   width,
+                      const Int   height,
+                      const Int   orgStride,
+                      const Int   refStride,
+                      const Int   log2Denom,
+                      const Int   weight,
+                      const Int   offset,
+                      const Bool  useHighPrecision)
+{
+  //const Int64 iSize          = iWidth*iHeight;
+  const Int64 realLog2Denom = useHighPrecision ? log2Denom : (log2Denom + (bitDepth - 8));
+  const Int64 realOffset    = ((Int64)offset)<<realLog2Denom;
+
+  Int64 SAD = 0;
+  for( Int y = 0; y < height; y++ )
+  {
+    for( Int x = 0; x < width; x++ )
+    {
+      SAD += abs(( ((Int64)pOrgPel[x] << (Int64) log2Denom) - ( (Int64) pRefPel[x] * (Int64) weight + (realOffset) ) ) );
+    }
+    pOrgPel += orgStride;
+    pRefPel += refStride;
+  }
+
+  //return (iSAD/iSize);
+  return SAD;
+}
+
+static
+Int64 xCalcSADvalueWPOptionalClip(const Int   bitDepth,
+                                  const Pel  *pOrgPel,
+                                  const Pel  *pRefPel,
+                                  const Int   width,
+                                  const Int   height,
+                                  const Int   orgStride,
+                                  const Int   refStride,
+                                  const Int   log2Denom,
+                                  const Int   weight,
+                                  const Int   offset,
+                                  const Bool  useHighPrecision,
+                                  const Bool  clipped)
+{
+  Int64 SAD = 0;
+  if (clipped)
+  {
+    const Int64 realLog2Denom = useHighPrecision ? 0 : (bitDepth - 8);
+    const Int64 realOffset    = (Int64)offset<<realLog2Denom;
+    const Int64 roundOffset = (log2Denom == 0) ? 0 : 1 << (log2Denom - 1);
+    const Int64 minValue = 0;
+    const Int64 maxValue = (1 << bitDepth) - 1;
+
+    for( Int y = 0; y < height; y++ )
+    {
+      for( Int x = 0; x < width; x++ )
+      {
+        Int64 scaledValue = Clip3(minValue, maxValue,  ((((Int64) pRefPel[x] * (Int64) weight + roundOffset) ) >>  (Int64) log2Denom) + realOffset);
+        SAD += abs((Int64)pOrgPel[x] -  scaledValue);
+      }
+      pOrgPel += orgStride;
+      pRefPel += refStride;
+    }
+  }
+  else
+  {
+    //const Int64 iSize          = iWidth*iHeight;
+    const Int64 realLog2Denom = useHighPrecision ? log2Denom : (log2Denom + (bitDepth - 8));
+    const Int64 realOffset    = ((Int64)offset)<<realLog2Denom;
+
+    for( Int y = 0; y < height; y++ )
+    {
+      for( Int x = 0; x < width; x++ )
+      {
+        SAD += abs(( ((Int64)pOrgPel[x] << (Int64) log2Denom) - ( (Int64) pRefPel[x] * (Int64) weight + (realOffset) ) ) );
+      }
+      pOrgPel += orgStride;
+      pRefPel += refStride;
+    }
+  }
+  return SAD;
+}
Index: branches/HTM-15.2-dev/source/Lib/TLibEncoder/WeightPredAnalysis.h
===================================================================
--- branches/HTM-15.2-dev/source/Lib/TLibEncoder/WeightPredAnalysis.h	(revision 1359)
+++ branches/HTM-15.2-dev/source/Lib/TLibEncoder/WeightPredAnalysis.h	(revision 1360)
@@ -52,17 +52,6 @@
 
   Bool  xSelectWP            (TComSlice *const slice, const Int log2Denom);
+  Bool  xSelectWPHistExtClip (TComSlice *const slice, const Int log2Denom, const Bool bDoEnhancement, const Bool bClipInitialSADWP, const Bool bUseHistogram);
   Bool  xUpdatingWPParameters(TComSlice *const slice, const Int log2Denom);
-
-  Int64 xCalcSADvalueWP      (const Int   bitDepth,
-                              const Pel  *pOrgPel,
-                              const Pel  *pRefPel,
-                              const Int   iWidth,
-                              const Int   iHeight,
-                              const Int   iOrgStride,
-                              const Int   iRefStride,
-                              const Int   iLog2Denom,
-                              const Int   iWeight,
-                              const Int   iOffset,
-                              const Bool  useHighPrecisionPredictionWeighting);
 
 public:
@@ -72,5 +61,5 @@
   // WP analysis :
   Void  xCalcACDCParamSlice  (TComSlice *const slice);
-  Void  xEstimateWPParamSlice(TComSlice *const slice);
+  Void  xEstimateWPParamSlice(TComSlice *const slice, const WeightedPredictionMethod method);
   Void  xCheckWPEnable       (TComSlice *const slice);
 };
