Ticket #990: patch-ticket-990.txt

File patch-ticket-990.txt, 36.5 KB (added by karlsharman, 9 years ago)

Fix of ticket 990 - correction of lambda for luma and chroma.

Line 
1diff -c -p -r HEVC_HM11.0/source/Lib/TLibCommon/TComSlice.cpp HEVC_Patched_990/source/Lib/TLibCommon/TComSlice.cpp
2*** HEVC_HM11.0/source/Lib/TLibCommon/TComSlice.cpp     2013-06-07 15:36:28.000000000 +0100
3--- HEVC_Patched_990/source/Lib/TLibCommon/TComSlice.cpp        2013-08-09 09:53:44.000000000 +0100
4*************** TComSlice::TComSlice()
5*** 70,79 ****
6  , m_pcPic                         ( NULL )
7  , m_colFromL0Flag                 ( 1 )
8  , m_colRefIdx                     ( 0 )
9! #if SAO_CHROMA_LAMBDA
10! , m_dLambdaLuma( 0.0 )
11! , m_dLambdaChroma( 0.0 )
12! #else
13  , m_dLambda                       ( 0.0 )
14  #endif
15  , m_uiTLayer                      ( 0 )
16--- 70,76 ----
17  , m_pcPic                         ( NULL )
18  , m_colFromL0Flag                 ( 1 )
19  , m_colRefIdx                     ( 0 )
20! #if !SAO_CHROMA_LAMBDA
21  , m_dLambda                       ( 0.0 )
22  #endif
23  , m_uiTLayer                      ( 0 )
24*************** TComSlice::TComSlice()
25*** 103,109 ****
26    m_aiNumRefIdx[0] = m_aiNumRefIdx[1] = 0;
27   
28    initEqualRef();
29!   
30    for ( Int idx = 0; idx < MAX_NUM_REF; idx++ )
31    {
32      m_list1IdxToList0Idx[idx] = -1;
33--- 100,109 ----
34    m_aiNumRefIdx[0] = m_aiNumRefIdx[1] = 0;
35   
36    initEqualRef();
37!   for (UInt component = 0; component < 3; component++)
38!   {
39!     m_lambdas[component] = 0.0;
40!   }
41    for ( Int idx = 0; idx < MAX_NUM_REF; idx++ )
42    {
43      m_list1IdxToList0Idx[idx] = -1;
44*************** Void TComSlice::copySliceInfo(TComSlice
45*** 692,699 ****
46    m_colFromL0Flag        = pSrc->m_colFromL0Flag;
47    m_colRefIdx            = pSrc->m_colRefIdx;
48  #if SAO_CHROMA_LAMBDA
49!   m_dLambdaLuma          = pSrc->m_dLambdaLuma;
50!   m_dLambdaChroma        = pSrc->m_dLambdaChroma;
51  #else
52    m_dLambda              = pSrc->m_dLambda;
53  #endif
54--- 692,698 ----
55    m_colFromL0Flag        = pSrc->m_colFromL0Flag;
56    m_colRefIdx            = pSrc->m_colRefIdx;
57  #if SAO_CHROMA_LAMBDA
58!   setLambdas(pSrc->getLambdas());
59  #else
60    m_dLambda              = pSrc->m_dLambda;
61  #endif
62diff -c -p -r HEVC_HM11.0/source/Lib/TLibCommon/TComSlice.h HEVC_Patched_990/source/Lib/TLibCommon/TComSlice.h
63*** HEVC_HM11.0/source/Lib/TLibCommon/TComSlice.h       2013-06-07 15:36:28.000000000 +0100
64--- HEVC_Patched_990/source/Lib/TLibCommon/TComSlice.h  2013-08-09 09:53:44.000000000 +0100
65*************** private:
66*** 1165,1172 ****
67 
68 
69  #if SAO_CHROMA_LAMBDA
70!   Double      m_dLambdaLuma;
71!   Double      m_dLambdaChroma;
72  #else
73    Double      m_dLambda;
74  #endif
75--- 1165,1171 ----
76 
77 
78  #if SAO_CHROMA_LAMBDA
79!   Double      m_lambdas[3];
80  #else
81    Double      m_dLambda;
82  #endif
83*************** public:
84*** 1316,1324 ****
85    Bool      isInterP        ()                          { return  m_eSliceType == P_SLICE;  }
86   
87  #if SAO_CHROMA_LAMBDA 
88!   Void      setLambda( Double d, Double e ) { m_dLambdaLuma = d; m_dLambdaChroma = e;}
89!   Double    getLambdaLuma() { return m_dLambdaLuma;        }
90!   Double    getLambdaChroma() { return m_dLambdaChroma;        }
91  #else
92    Void      setLambda( Double d ) { m_dLambda = d; }
93    Double    getLambda() { return m_dLambda;        }
94--- 1315,1322 ----
95    Bool      isInterP        ()                          { return  m_eSliceType == P_SLICE;  }
96   
97  #if SAO_CHROMA_LAMBDA 
98!   Void      setLambdas ( const Double lambdas[3] ) { for (UInt component = 0; component < 3; component++) m_lambdas[component] = lambdas[component]; }
99!   const Double* getLambdas() const { return m_lambdas; }
100  #else
101    Void      setLambda( Double d ) { m_dLambda = d; }
102    Double    getLambda() { return m_dLambda;        }
103diff -c -p -r HEVC_HM11.0/source/Lib/TLibCommon/TComTrQuant.h HEVC_Patched_990/source/Lib/TLibCommon/TComTrQuant.h
104*** HEVC_HM11.0/source/Lib/TLibCommon/TComTrQuant.h     2013-01-25 10:29:33.000000000 +0000
105--- HEVC_Patched_990/source/Lib/TLibCommon/TComTrQuant.h        2013-08-09 09:53:44.000000000 +0100
106*************** public:
107*** 149,156 ****
108    Void setQPforQuant( Int qpy, TextType eTxtType, Int qpBdOffset, Int chromaQPOffset);
109 
110  #if RDOQ_CHROMA_LAMBDA
111!   Void setLambda(Double dLambdaLuma, Double dLambdaChroma) { m_dLambdaLuma = dLambdaLuma; m_dLambdaChroma = dLambdaChroma; }
112!   Void selectLambda(TextType eTType) { m_dLambda = (eTType == TEXT_LUMA) ? m_dLambdaLuma : m_dLambdaChroma; }
113  #else
114    Void setLambda(Double dLambda) { m_dLambda = dLambda;}
115  #endif
116--- 149,156 ----
117    Void setQPforQuant( Int qpy, TextType eTxtType, Int qpBdOffset, Int chromaQPOffset);
118 
119  #if RDOQ_CHROMA_LAMBDA
120!   Void setLambdas ( const Double lambdas[3] ) { for (UInt component = 0; component < 3; component++) m_lambdas[component] = lambdas[component]; }
121!   Void selectLambda(TextType eTType) { m_dLambda = (eTType == TEXT_LUMA) ? m_lambdas[0] : ((eTType == TEXT_CHROMA_U) ? m_lambdas[1] : m_lambdas[2]); }
122  #else
123    Void setLambda(Double dLambda) { m_dLambda = dLambda;}
124  #endif
125*************** protected:
126*** 206,213 ****
127   
128    QpParam  m_cQP;
129  #if RDOQ_CHROMA_LAMBDA
130!   Double   m_dLambdaLuma;
131!   Double   m_dLambdaChroma;
132  #endif
133    Double   m_dLambda;
134    UInt     m_uiRDOQOffset;
135--- 206,212 ----
136   
137    QpParam  m_cQP;
138  #if RDOQ_CHROMA_LAMBDA
139!   Double   m_lambdas[3];
140  #endif
141    Double   m_dLambda;
142    UInt     m_uiRDOQOffset;
143diff -c -p -r HEVC_HM11.0/source/Lib/TLibEncoder/TEncGOP.cpp HEVC_Patched_990/source/Lib/TLibEncoder/TEncGOP.cpp
144*** HEVC_HM11.0/source/Lib/TLibEncoder/TEncGOP.cpp      2013-06-07 15:36:28.000000000 +0100
145--- HEVC_Patched_990/source/Lib/TLibEncoder/TEncGOP.cpp 2013-08-09 09:53:44.000000000 +0100
146*************** Void TEncGOP::compressGOP( Int iPOCLast,
147*** 1503,1511 ****
148 
149  #if SAO_CHROMA_LAMBDA
150  #if SAO_ENCODING_CHOICE
151!               m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma(), pcPic->getSlice(0)->getDepth());
152  #else
153!               m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdaLuma(), pcPic->getSlice(0)->getLambdaChroma());
154  #endif
155  #else
156                m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambda());
157--- 1503,1511 ----
158 
159  #if SAO_CHROMA_LAMBDA
160  #if SAO_ENCODING_CHOICE
161!               m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdas(), pcPic->getSlice(0)->getDepth());
162  #else
163!               m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambdas());
164  #endif
165  #else
166                m_pcSAO->SAOProcess(&cSaoParam, pcPic->getSlice(0)->getLambda());
167diff -c -p -r HEVC_HM11.0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp HEVC_Patched_990/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
168*** HEVC_HM11.0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp     2013-06-07 15:36:28.000000000 +0100
169--- HEVC_Patched_990/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp        2013-08-09 09:53:44.000000000 +0100
170*************** Void TEncSampleAdaptiveOffset::resetStat
171*** 1667,1675 ****
172   * \param dLambdaChroma
173   */
174  #if SAO_ENCODING_CHOICE
175! Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambdaLuma, Double dLambdaChroma, Int depth)
176  #else
177! Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, Double dLambdaLuma, Double dLambdaChroma)
178  #endif
179  #else
180  /** Sample adaptive offset process
181--- 1667,1675 ----
182   * \param dLambdaChroma
183   */
184  #if SAO_ENCODING_CHOICE
185! Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, const Double dLambdas[3], Int depth)
186  #else
187! Void TEncSampleAdaptiveOffset::SAOProcess(SAOParam *pcSaoParam, const Double dLambdas[3])
188  #endif
189  #else
190  /** Sample adaptive offset process
191*************** Void TEncSampleAdaptiveOffset::SAOProces
192*** 1696,1704 ****
193    if ( m_saoLcuBasedOptimization)
194    {
195  #if SAO_ENCODING_CHOICE
196!     rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma, depth);
197  #else
198!     rdoSaoUnitAll(pcSaoParam, dLambdaLuma, dLambdaChroma);
199  #endif
200    }
201    else
202--- 1696,1704 ----
203    if ( m_saoLcuBasedOptimization)
204    {
205  #if SAO_ENCODING_CHOICE
206!     rdoSaoUnitAll(pcSaoParam, dLambdas, depth);
207  #else
208!     rdoSaoUnitAll(pcSaoParam, dLambdas);
209  #endif
210    }
211    else
212*************** Void TEncSampleAdaptiveOffset::SAOProces
213*** 1706,1712 ****
214      pcSaoParam->bSaoFlag[0] = 1;
215      pcSaoParam->bSaoFlag[1] = 0;
216      dCostFinal = 0;
217!     Double lambdaRdo =  dLambdaLuma;
218      resetStats();
219      getSaoStats(pcSaoParam->psSaoPart[0], 0);
220      runQuadTreeDecision(pcSaoParam->psSaoPart[0], 0, dCostFinal, m_uiMaxSplitLevel, lambdaRdo, 0);
221--- 1706,1712 ----
222      pcSaoParam->bSaoFlag[0] = 1;
223      pcSaoParam->bSaoFlag[1] = 0;
224      dCostFinal = 0;
225!     Double lambdaRdo =  dLambdas[0];
226      resetStats();
227      getSaoStats(pcSaoParam->psSaoPart[0], 0);
228      runQuadTreeDecision(pcSaoParam->psSaoPart[0], 0, dCostFinal, m_uiMaxSplitLevel, lambdaRdo, 0);
229*************** Void TEncSampleAdaptiveOffset::assignSao
230*** 1851,1859 ****
231   * \param lambdaChroma
232   */
233  #if SAO_ENCODING_CHOICE
234! Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma, Int depth)
235  #else
236! Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma)
237  #endif
238  {
239 
240--- 1851,1859 ----
241   * \param lambdaChroma
242   */
243  #if SAO_ENCODING_CHOICE
244! Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, const Double dLambdas[3], Int depth)
245  #else
246! Void TEncSampleAdaptiveOffset::rdoSaoUnitAll(SAOParam *saoParam, const Double dLambdas[3])
247  #endif
248  {
249 
250*************** Void TEncSampleAdaptiveOffset::rdoSaoUni
251*** 1978,1985 ****
252 
253         }
254        }
255!       saoComponentParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, 0,  lambda, &mergeSaoParam[0][0], &compDistortion[0]);
256!       sao2ChromaParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, lambdaChroma, &mergeSaoParam[1][0], &mergeSaoParam[2][0], &compDistortion[0]);
257       if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
258        {
259          // Cost of new SAO_params
260--- 1978,1985 ----
261 
262         }
263        }
264!       saoComponentParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, 0, dLambdas[0], &mergeSaoParam[0][0], &compDistortion[0]);
265!       sao2ChromaParamDist(allowMergeLeft, allowMergeUp, saoParam, addr, addrUp, addrLeft, dLambdas, &mergeSaoParam[1][0], &mergeSaoParam[2][0], &compDistortion[0]);
266       if( saoParam->bSaoFlag[0] || saoParam->bSaoFlag[1] )
267        {
268          // Cost of new SAO_params
269*************** Void TEncSampleAdaptiveOffset::saoCompon
270*** 2330,2343 ****
271      }
272    }
273  }
274! Void TEncSampleAdaptiveOffset::sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Double lambda, SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion)
275  {
276    Int typeIdx;
277 
278    Int64 estDist[2];
279    Int classIdx;
280    Int shift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
281!   Int64 bestDist = 0;
282 
283    SaoLcuParam*  saoLcuParam[2] = {&(saoParam->saoLcuParam[1][addr]), &(saoParam->saoLcuParam[2][addr])};
284    SaoLcuParam*  saoLcuParamNeighbor[2] = {NULL, NULL};
285--- 2330,2343 ----
286      }
287    }
288  }
289! Void TEncSampleAdaptiveOffset::sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, const Double lambdas[3], SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion)
290  {
291    Int typeIdx;
292 
293    Int64 estDist[2];
294    Int classIdx;
295    Int shift = 2 * DISTORTION_PRECISION_ADJUSTMENT(g_bitDepthC-8);
296!   Double bestDistOverLambda = 0;
297 
298    SaoLcuParam*  saoLcuParam[2] = {&(saoParam->saoLcuParam[1][addr]), &(saoParam->saoLcuParam[2][addr])};
299    SaoLcuParam*  saoLcuParamNeighbor[2] = {NULL, NULL};
300*************** Void TEncSampleAdaptiveOffset::sao2Chrom
301*** 2363,2379 ****
302    Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
303 
304    SaoLcuParam   saoLcuParamRdo[2];   
305-   Double   estRate = 0;
306 
307    resetSaoUnit(&saoLcuParamRdo[0]);
308    resetSaoUnit(&saoLcuParamRdo[1]);
309 
310    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
311    m_pcRDGoOnSbacCoder->resetBits();
312    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[0], 1);
313    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[1], 2);
314   
315-   costPartBest = m_pcEntropyCoder->getNumberOfWrittenBits()*lambda ;
316    copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] );
317    copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] );
318 
319--- 2363,2381 ----
320    Double  currentRdCostTableBo[MAX_NUM_SAO_CLASS];
321 
322    SaoLcuParam   saoLcuParamRdo[2];   
323 
324    resetSaoUnit(&saoLcuParamRdo[0]);
325    resetSaoUnit(&saoLcuParamRdo[1]);
326 
327    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
328    m_pcRDGoOnSbacCoder->resetBits();
329+
330    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[0], 1);
331+   const UInt bitsWritten = m_pcEntropyCoder->getNumberOfWrittenBits();
332+   costPartBest = bitsWritten * lambdas[1];
333    m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[1], 2);
334+   costPartBest += (m_pcEntropyCoder->getNumberOfWrittenBits() - bitsWritten) * lambdas[2];
335   
336    copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] );
337    copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] );
338 
339*************** Void TEncSampleAdaptiveOffset::sao2Chrom
340*** 2386,2392 ****
341        {
342          Double currentRDCost = 0.0;
343          bestRDCostTableBo = MAX_DOUBLE;
344!         estDist[compIdx] = estSaoTypeDist(compIdx+1, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
345          for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
346          {
347            currentRDCost = 0.0;
348--- 2388,2394 ----
349        {
350          Double currentRDCost = 0.0;
351          bestRDCostTableBo = MAX_DOUBLE;
352!         estDist[compIdx] = estSaoTypeDist(compIdx+1, typeIdx, shift, lambdas[compIdx + 1], currentDistortionTableBo, currentRdCostTableBo);
353          for(Int i=0; i< SAO_MAX_BO_CLASSES -SAO_BO_LEN +1; i++)
354          {
355            currentRDCost = 0.0;
356*************** Void TEncSampleAdaptiveOffset::sao2Chrom
357*** 2413,2424 ****
358      }
359      else
360      {
361!       estDist[0] = estSaoTypeDist(1, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
362!       estDist[1] = estSaoTypeDist(2, typeIdx, shift, lambda, currentDistortionTableBo, currentRdCostTableBo);
363      }
364 
365      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
366      m_pcRDGoOnSbacCoder->resetBits();
367 
368      for(Int compIdx = 0; compIdx < 2; compIdx++)
369      {
370--- 2415,2428 ----
371      }
372      else
373      {
374!       estDist[0] = estSaoTypeDist(1, typeIdx, shift, lambdas[1], currentDistortionTableBo, currentRdCostTableBo);
375!       estDist[1] = estSaoTypeDist(2, typeIdx, shift, lambdas[2], currentDistortionTableBo, currentRdCostTableBo);
376      }
377 
378      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
379      m_pcRDGoOnSbacCoder->resetBits();
380+     m_dCost[1][typeIdx] = 0;
381+     UInt lastWrittenBits=0;
382 
383      for(Int compIdx = 0; compIdx < 2; compIdx++)
384      {
385*************** Void TEncSampleAdaptiveOffset::sao2Chrom
386*** 2434,2453 ****
387        }
388 
389        m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[compIdx], compIdx+1);
390      }
391!     estRate = m_pcEntropyCoder->getNumberOfWrittenBits();
392!     m_dCost[1][typeIdx] = (Double)((Double)(estDist[0] + estDist[1])  + lambda * (Double) estRate);
393!     
394      if(m_dCost[1][typeIdx] < costPartBest)
395      {
396        costPartBest = m_dCost[1][typeIdx];
397!       copySaoUnit(saoLcuParam[0], &saoLcuParamRdo[0] );
398!       copySaoUnit(saoLcuParam[1], &saoLcuParamRdo[1] );
399!       bestDist = (estDist[0]+estDist[1]);       
400      }
401    }
402 
403!   distortion[0] += ((Double)bestDist/lambda);
404    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
405    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[0], 1);
406    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[1], 2);
407--- 2438,2461 ----
408        }
409 
410        m_pcEntropyCoder->encodeSaoOffset(&saoLcuParamRdo[compIdx], compIdx+1);
411+       const UInt newWrittenBits = m_pcEntropyCoder->getNumberOfWrittenBits();
412+       m_dCost[1][typeIdx] += (Double)((Double)(estDist[compIdx]) + (lambdas[compIdx + 1] * (Double)(newWrittenBits - lastWrittenBits)));
413+       lastWrittenBits = newWrittenBits;
414      }
415!
416      if(m_dCost[1][typeIdx] < costPartBest)
417      {
418        costPartBest = m_dCost[1][typeIdx];
419!       bestDistOverLambda = 0;
420!       for(Int compIdx = 0; compIdx < 2; compIdx++)
421!       {
422!         copySaoUnit(saoLcuParam[compIdx], &saoLcuParamRdo[compIdx] );
423!         bestDistOverLambda += (estDist[compIdx] / lambdas[compIdx + 1]);
424!       }     
425      }
426    }
427 
428!   distortion[0] += bestDistOverLambda;
429    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[0][CI_TEMP_BEST]);
430    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[0], 1);
431    m_pcEntropyCoder->encodeSaoOffset(saoLcuParam[1], 2);
432*************** Void TEncSampleAdaptiveOffset::sao2Chrom
433*** 2490,2496 ****
434          copySaoUnit(saoMergeParam[compIdx][idxNeighbor], saoLcuParamNeighbor[compIdx] );
435          saoMergeParam[compIdx][idxNeighbor]->mergeUpFlag   = idxNeighbor;
436          saoMergeParam[compIdx][idxNeighbor]->mergeLeftFlag = !idxNeighbor;
437!         distortion[idxNeighbor+1] += ((Double)estDist[compIdx]/lambda);
438        }
439      }
440    }
441--- 2498,2504 ----
442          copySaoUnit(saoMergeParam[compIdx][idxNeighbor], saoLcuParamNeighbor[compIdx] );
443          saoMergeParam[compIdx][idxNeighbor]->mergeUpFlag   = idxNeighbor;
444          saoMergeParam[compIdx][idxNeighbor]->mergeLeftFlag = !idxNeighbor;
445!         distortion[idxNeighbor+1] += ((Double)estDist[compIdx]/lambdas[compIdx + 1]);
446        }
447      }
448    }
449diff -c -p -r HEVC_HM11.0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h HEVC_Patched_990/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h
450*** HEVC_HM11.0/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h       2013-04-23 15:08:58.000000000 +0100
451--- HEVC_Patched_990/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h  2013-08-09 09:53:44.000000000 +0100
452*************** public:
453*** 96,104 ****
454    Void resetStats();
455  #if SAO_CHROMA_LAMBDA
456  #if SAO_ENCODING_CHOICE
457!   Void SAOProcess(SAOParam *pcSaoParam, Double dLambda, Double dLambdaChroma, Int depth);
458  #else
459!   Void SAOProcess(SAOParam *pcSaoParam, Double dLambda, Double dLambdaChroma);
460  #endif
461  #else
462    Void SAOProcess(SAOParam *pcSaoParam, Double dLambda);
463--- 96,104 ----
464    Void resetStats();
465  #if SAO_CHROMA_LAMBDA
466  #if SAO_ENCODING_CHOICE
467!   Void SAOProcess(SAOParam *pcSaoParam, const Double dLambdas[3], Int depth);
468  #else
469!   Void SAOProcess(SAOParam *pcSaoParam, const Double dLambdas[3]);
470  #endif
471  #else
472    Void SAOProcess(SAOParam *pcSaoParam, Double dLambda);
473*************** public:
474*** 118,129 ****
475    Void assignSaoUnitSyntax(SaoLcuParam* saoLcuParam,  SAOQTPart* saoPart, Bool &oneUnitFlag, Int yCbCr);
476    Void checkMerge(SaoLcuParam * lcuParamCurr,SaoLcuParam * lcuParamCheck, Int dir);
477  #if SAO_ENCODING_CHOICE
478!   Void rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma, Int depth);
479  #else
480!   Void rdoSaoUnitAll(SAOParam *saoParam, Double lambda, Double lambdaChroma);
481  #endif
482    Void saoComponentParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda, SaoLcuParam *compSaoParam, Double *distortion);
483!   Void sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Double lambda, SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion);
484    inline Int64 estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift);
485    inline Int64 estIterOffset(Int typeIdx, Int classIdx, Double lambda, Int64 offsetInput, Int64 count, Int64 offsetOrg, Int shift, Int bitIncrease, Int *currentDistortionTableBo, Double *currentRdCostTableBo, Int offsetTh );
486    inline Int64 estSaoTypeDist(Int compIdx, Int typeIdx, Int shift, Double lambda, Int *currentDistortionTableBo, Double *currentRdCostTableBo);
487--- 118,129 ----
488    Void assignSaoUnitSyntax(SaoLcuParam* saoLcuParam,  SAOQTPart* saoPart, Bool &oneUnitFlag, Int yCbCr);
489    Void checkMerge(SaoLcuParam * lcuParamCurr,SaoLcuParam * lcuParamCheck, Int dir);
490  #if SAO_ENCODING_CHOICE
491!   Void rdoSaoUnitAll(SAOParam *saoParam, const Double dLambdas[3], Int depth);
492  #else
493!   Void rdoSaoUnitAll(SAOParam *saoParam, const Double dLambdas[3]);
494  #endif
495    Void saoComponentParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, Int yCbCr, Double lambda, SaoLcuParam *compSaoParam, Double *distortion);
496!   Void sao2ChromaParamDist(Int allowMergeLeft, Int allowMergeUp, SAOParam *saoParam, Int addr, Int addrUp, Int addrLeft, const Double lambdas[3], SaoLcuParam *crSaoParam, SaoLcuParam *cbSaoParam, Double *distortion);
497    inline Int64 estSaoDist(Int64 count, Int64 offset, Int64 offsetOrg, Int shift);
498    inline Int64 estIterOffset(Int typeIdx, Int classIdx, Double lambda, Int64 offsetInput, Int64 count, Int64 offsetOrg, Int shift, Int bitIncrease, Int *currentDistortionTableBo, Double *currentRdCostTableBo, Int offsetTh );
499    inline Int64 estSaoTypeDist(Int compIdx, Int typeIdx, Int shift, Double lambda, Int *currentDistortionTableBo, Double *currentRdCostTableBo);
500diff -c -p -r HEVC_HM11.0/source/Lib/TLibEncoder/TEncSearch.cpp HEVC_Patched_990/source/Lib/TLibEncoder/TEncSearch.cpp
501*** HEVC_HM11.0/source/Lib/TLibEncoder/TEncSearch.cpp   2013-08-08 16:44:24.000000000 +0100
502--- HEVC_Patched_990/source/Lib/TLibEncoder/TEncSearch.cpp      2013-08-09 09:53:44.000000000 +0100
503*************** TEncSearch::xIntraCodingChromaBlk( TComD
504*** 1301,1307 ****
505      m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
506 
507  #if RDOQ_CHROMA_LAMBDA
508!     m_pcTrQuant->selectLambda      (TEXT_CHROMA); 
509  #endif
510      m_pcTrQuant->transformNxN      ( pcCU, piResi, uiStride, pcCoeff,
511  #if ADAPTIVE_QP_SELECTION
512--- 1301,1307 ----
513      m_pcTrQuant->setQPforQuant     ( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
514 
515  #if RDOQ_CHROMA_LAMBDA
516!     m_pcTrQuant->selectLambda      (uiChromaId > 0 ? TEXT_CHROMA_V : TEXT_CHROMA_U); 
517  #endif
518      m_pcTrQuant->transformNxN      ( pcCU, piResi, uiStride, pcCoeff,
519  #if ADAPTIVE_QP_SELECTION
520*************** Void TEncSearch::xEstimateResidualQT( TC
521*** 4770,4776 ****
522        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
523 
524  #if RDOQ_CHROMA_LAMBDA
525!       m_pcTrQuant->selectLambda(TEXT_CHROMA);
526  #endif
527 
528        m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU,
529--- 4770,4776 ----
530        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
531 
532  #if RDOQ_CHROMA_LAMBDA
533!       m_pcTrQuant->selectLambda(TEXT_CHROMA_U);
534  #endif
535 
536        m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU,
537*************** Void TEncSearch::xEstimateResidualQT( TC
538*** 4779,4784 ****
539--- 4779,4788 ----
540  #endif       
541                                   trWidthC, trHeightC, uiAbsSumU, TEXT_CHROMA_U, uiAbsPartIdx );
542 
543+ #if RDOQ_CHROMA_LAMBDA
544+       m_pcTrQuant->selectLambda(TEXT_CHROMA_V);
545+ #endif
546+
547        curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
548        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
549        m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrV,
550*************** Void TEncSearch::xEstimateResidualQT( TC
551*** 5179,5185 ****
552        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
553 
554  #if RDOQ_CHROMA_LAMBDA
555!       m_pcTrQuant->selectLambda(TEXT_CHROMA);
556  #endif
557 
558        m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU,
559--- 5183,5189 ----
560        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
561 
562  #if RDOQ_CHROMA_LAMBDA
563!       m_pcTrQuant->selectLambda(TEXT_CHROMA_U);
564  #endif
565 
566        m_pcTrQuant->transformNxN( pcCU, pcResi->getCbAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrU,
567*************** Void TEncSearch::xEstimateResidualQT( TC
568*** 5187,5192 ****
569--- 5191,5201 ----
570          pcArlCoeffCurrU,
571  #endif       
572          trWidthC, trHeightC, uiAbsSumTransformSkipU, TEXT_CHROMA_U, uiAbsPartIdx, true );
573+
574+ #if RDOQ_CHROMA_LAMBDA
575+       m_pcTrQuant->selectLambda(TEXT_CHROMA_V);
576+ #endif
577+
578        curChromaQpOffset = pcCU->getSlice()->getPPS()->getChromaCrQpOffset() + pcCU->getSlice()->getSliceQpDeltaCr();
579        m_pcTrQuant->setQPforQuant( pcCU->getQP( 0 ), TEXT_CHROMA, pcCU->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset );
580        m_pcTrQuant->transformNxN( pcCU, pcResi->getCrAddr(absTUPartIdxC), pcResi->getCStride(), pcCoeffCurrV,
581diff -c -p -r HEVC_HM11.0/source/Lib/TLibEncoder/TEncSlice.cpp HEVC_Patched_990/source/Lib/TLibEncoder/TEncSlice.cpp
582*** HEVC_HM11.0/source/Lib/TLibEncoder/TEncSlice.cpp    2013-06-07 15:36:28.000000000 +0100
583--- HEVC_Patched_990/source/Lib/TLibEncoder/TEncSlice.cpp       2013-08-09 09:53:44.000000000 +0100
584*************** Void TEncSlice::initEncSlice( TComPic* p
585*** 335,365 ****
586  #if WEIGHTED_CHROMA_DISTORTION
587  // for RDO
588    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
589!   Double weight = 1.0;
590    Int qpc;
591    Int chromaQPOffset;
592 
593    chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
594    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
595!   weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
596!   m_pcRdCost->setCbDistortionWeight(weight);
597 
598    chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
599    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
600!   weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
601!   m_pcRdCost->setCrDistortionWeight(weight);
602  #endif
603 
604  #if RDOQ_CHROMA_LAMBDA
605  // for RDOQ
606!   m_pcTrQuant->setLambda( dLambda, dLambda / weight );   
607  #else
608    m_pcTrQuant->setLambda( dLambda );
609  #endif
610 
611  #if SAO_CHROMA_LAMBDA
612  // For SAO
613!   rpcSlice   ->setLambda( dLambda, dLambda / weight ); 
614  #else
615    rpcSlice   ->setLambda( dLambda );
616  #endif
617--- 335,367 ----
618  #if WEIGHTED_CHROMA_DISTORTION
619  // for RDO
620    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
621!   Double weight[2] = {1.0, 1.0};
622    Int qpc;
623    Int chromaQPOffset;
624 
625    chromaQPOffset = rpcSlice->getPPS()->getChromaCbQpOffset() + rpcSlice->getSliceQpDeltaCb();
626    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
627!   weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
628!   m_pcRdCost->setCbDistortionWeight(weight[0]);
629 
630    chromaQPOffset = rpcSlice->getPPS()->getChromaCrQpOffset() + rpcSlice->getSliceQpDeltaCr();
631    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
632!   weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
633!   m_pcRdCost->setCrDistortionWeight(weight[1]);
634!
635!   const Double lambdaArray[3] = {dLambda, (dLambda / weight[0]), (dLambda / weight[1])};
636  #endif
637 
638  #if RDOQ_CHROMA_LAMBDA
639  // for RDOQ
640!   m_pcTrQuant->setLambdas( lambdaArray );   
641  #else
642    m_pcTrQuant->setLambda( dLambda );
643  #endif
644 
645  #if SAO_CHROMA_LAMBDA
646  // For SAO
647!   rpcSlice   ->setLambdas( lambdaArray ); 
648  #else
649    rpcSlice   ->setLambda( dLambda );
650  #endif
651*************** Void TEncSlice::resetQP( TComPic* pic, I
652*** 460,490 ****
653  #if WEIGHTED_CHROMA_DISTORTION
654    // for RDO
655    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
656!   Double weight;
657    Int qpc;
658    Int chromaQPOffset;
659 
660    chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
661    qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
662!   weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
663!   m_pcRdCost->setCbDistortionWeight(weight);
664 
665    chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
666    qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
667!   weight = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
668!   m_pcRdCost->setCrDistortionWeight(weight);
669  #endif
670 
671  #if RDOQ_CHROMA_LAMBDA
672    // for RDOQ
673!   m_pcTrQuant->setLambda( lambda, lambda / weight );
674  #else
675    m_pcTrQuant->setLambda( lambda );
676  #endif
677 
678  #if SAO_CHROMA_LAMBDA
679    // For SAO
680!   slice   ->setLambda( lambda, lambda / weight );
681  #else
682    slice   ->setLambda( lambda );
683  #endif
684--- 462,494 ----
685  #if WEIGHTED_CHROMA_DISTORTION
686    // for RDO
687    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
688!   Double weight[2] = {1.0, 1.0};
689    Int qpc;
690    Int chromaQPOffset;
691 
692    chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
693    qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
694!   weight[0] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
695!   m_pcRdCost->setCbDistortionWeight(weight[0]);
696 
697    chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
698    qpc = Clip3( 0, 57, sliceQP + chromaQPOffset);
699!   weight[1] = pow( 2.0, (sliceQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
700!   m_pcRdCost->setCrDistortionWeight(weight[1]);
701!
702!   const Double lambdaArray[3] = {lambda, (lambda / weight[0]), (lambda / weight[1])};
703  #endif
704 
705  #if RDOQ_CHROMA_LAMBDA
706    // for RDOQ
707!   m_pcTrQuant->setLambdas( lambdaArray );
708  #else
709    m_pcTrQuant->setLambda( lambda );
710  #endif
711 
712  #if SAO_CHROMA_LAMBDA
713    // For SAO
714!   slice   ->setLambdas( lambdaArray ); 
715  #else
716    slice   ->setLambda( lambda );
717  #endif
718*************** Void TEncSlice::precompressSlice( TComPi
719*** 675,704 ****
720      // for RDO
721      // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
722      Int iQP = m_piRdPicQp    [uiQpIdx];
723!     Double weight = 1.0;
724      Int qpc;
725      Int chromaQPOffset;
726 
727      chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
728      qpc = Clip3( 0, 57, iQP + chromaQPOffset);
729!     weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
730!     m_pcRdCost->setCbDistortionWeight(weight);
731 
732      chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
733      qpc = Clip3( 0, 57, iQP + chromaQPOffset);
734!     weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
735!     m_pcRdCost->setCrDistortionWeight(weight);
736  #endif
737 
738  #if RDOQ_CHROMA_LAMBDA
739      // for RDOQ
740!     m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
741  #else
742      m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
743  #endif
744  #if SAO_CHROMA_LAMBDA
745      // For SAO
746!     pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx], m_pdRdPicLambda[uiQpIdx] / weight );
747  #else
748      pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
749  #endif
750--- 679,710 ----
751      // for RDO
752      // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
753      Int iQP = m_piRdPicQp    [uiQpIdx];
754!     Double weight[2] = {1.0, 1.0};
755      Int qpc;
756      Int chromaQPOffset;
757 
758      chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
759      qpc = Clip3( 0, 57, iQP + chromaQPOffset);
760!     weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
761!     m_pcRdCost->setCbDistortionWeight(weight[0]);
762 
763      chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
764      qpc = Clip3( 0, 57, iQP + chromaQPOffset);
765!     weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
766!     m_pcRdCost->setCrDistortionWeight(weight[1]);
767!
768!     const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdx], (m_pdRdPicLambda[uiQpIdx] / weight[0]), (m_pdRdPicLambda[uiQpIdx] / weight[1])};
769  #endif
770 
771  #if RDOQ_CHROMA_LAMBDA
772      // for RDOQ
773!     m_pcTrQuant   ->setLambdas             ( lambdaArray );
774  #else
775      m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
776  #endif
777  #if SAO_CHROMA_LAMBDA
778      // For SAO
779!     pcSlice       ->setLambdas             ( lambdaArray );
780  #else
781      pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdx] );
782  #endif
783*************** Void TEncSlice::precompressSlice( TComPi
784*** 731,760 ****
785  #if WEIGHTED_CHROMA_DISTORTION
786    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
787    Int iQP = m_piRdPicQp    [uiQpIdxBest];
788!   Double weight = 1.0;
789    Int qpc;
790    Int chromaQPOffset;
791 
792    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
793    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
794!   weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
795!   m_pcRdCost->setCbDistortionWeight(weight);
796 
797    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
798    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
799!   weight = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
800!   m_pcRdCost->setCrDistortionWeight(weight);
801  #endif
802 
803  #if RDOQ_CHROMA_LAMBDA
804    // for RDOQ
805!   m_pcTrQuant   ->setLambda( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight );
806  #else
807    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
808  #endif
809  #if SAO_CHROMA_LAMBDA
810    // For SAO
811!   pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest], m_pdRdPicLambda[uiQpIdxBest] / weight );
812  #else
813    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
814  #endif
815--- 737,768 ----
816  #if WEIGHTED_CHROMA_DISTORTION
817    // in RdCost there is only one lambda because the luma and chroma bits are not separated, instead we weight the distortion of chroma.
818    Int iQP = m_piRdPicQp    [uiQpIdxBest];
819!   Double weight[2] = {1.0, 1.0};
820    Int qpc;
821    Int chromaQPOffset;
822 
823    chromaQPOffset = pcSlice->getPPS()->getChromaCbQpOffset() + pcSlice->getSliceQpDeltaCb();
824    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
825!   weight[0] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
826!   m_pcRdCost->setCbDistortionWeight(weight[0]);
827 
828    chromaQPOffset = pcSlice->getPPS()->getChromaCrQpOffset() + pcSlice->getSliceQpDeltaCr();
829    qpc = Clip3( 0, 57, iQP + chromaQPOffset);
830!   weight[1] = pow( 2.0, (iQP-g_aucChromaScale[qpc])/3.0 );  // takes into account of the chroma qp mapping and chroma qp Offset
831!   m_pcRdCost->setCrDistortionWeight(weight[1]);
832!
833!   const Double lambdaArray[3] = {m_pdRdPicLambda[uiQpIdxBest], (m_pdRdPicLambda[uiQpIdxBest] / weight[0]), (m_pdRdPicLambda[uiQpIdxBest] / weight[1])};
834  #endif
835 
836  #if RDOQ_CHROMA_LAMBDA
837    // for RDOQ
838!   m_pcTrQuant   ->setLambdas             ( lambdaArray );
839  #else
840    m_pcTrQuant   ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
841  #endif
842  #if SAO_CHROMA_LAMBDA
843    // For SAO
844!   pcSlice       ->setLambdas             ( lambdaArray );
845  #else
846    pcSlice       ->setLambda              ( m_pdRdPicLambda[uiQpIdxBest] );
847  #endif
848*************** Void TEncSlice::compressSlice( TComPic*&
849*** 1090,1096 ****
850  #if RDOQ_CHROMA_LAMBDA
851            // set lambda for RDOQ
852            Double weight=m_pcRdCost->getChromaWeight();
853!           m_pcTrQuant->setLambda( estLambda, estLambda / weight );
854  #else
855            m_pcTrQuant->setLambda( estLambda );
856  #endif
857--- 1098,1105 ----
858  #if RDOQ_CHROMA_LAMBDA
859            // set lambda for RDOQ
860            Double weight=m_pcRdCost->getChromaWeight();
861!           const Double lambdaArray[3] = { estLambda, (estLambda / weight), (estLambda / weight) };
862!           m_pcTrQuant->setLambdas( lambdaArray );
863  #else
864            m_pcTrQuant->setLambda( estLambda );
865  #endif