1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Steve Borho <steve@borho.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
20 * This program is also available under a commercial proprietary license.
21 * For more information, contact us at license @ x265.com.
22 *****************************************************************************/
37 /* all weights and factors stored as FIX8 */
40 uint32_t m_chromaDistWeight
[2];
45 void setPsyRdScale(double scale
) { m_psyRdBase
= (uint32_t)floor(256.0 * scale
* 0.33); }
47 void setQP(const Slice
& slice
, int qp
)
51 /* Scale PSY RD factor by a slice type factor */
52 static const uint32_t psyScaleFix8
[3] = { 300, 256, 96 }; /* B, P, I */
53 m_psyRd
= (m_psyRdBase
* psyScaleFix8
[slice
.m_sliceType
]) >> 8;
55 setLambda(x265_lambda2_tab
[qp
], x265_lambda_tab
[qp
]);
56 if (slice
.m_sps
->chromaFormatIdc
== X265_CSP_I420
)
57 qpCb
= Clip3(QP_MIN
, QP_MAX_MAX
, (int)g_chromaScale
[qp
+ slice
.m_pps
->chromaQpOffset
[0]]);
59 qpCb
= X265_MIN(qp
+ slice
.m_pps
->chromaQpOffset
[0], QP_MAX_SPEC
);
60 int chroma_offset_idx
= X265_MIN(qp
- qpCb
+ 12, MAX_CHROMA_LAMBDA_OFFSET
);
61 uint16_t lambdaOffset
= m_psyRd
? x265_chroma_lambda2_offset_tab
[chroma_offset_idx
] : 256;
62 m_chromaDistWeight
[0] = lambdaOffset
;
64 if (slice
.m_sps
->chromaFormatIdc
== X265_CSP_I420
)
65 qpCr
= Clip3(QP_MIN
, QP_MAX_MAX
, (int)g_chromaScale
[qp
+ slice
.m_pps
->chromaQpOffset
[0]]);
67 qpCr
= X265_MIN(qp
+ slice
.m_pps
->chromaQpOffset
[0], QP_MAX_SPEC
);
68 chroma_offset_idx
= X265_MIN(qp
- qpCr
+ 12, MAX_CHROMA_LAMBDA_OFFSET
);
69 lambdaOffset
= m_psyRd
? x265_chroma_lambda2_offset_tab
[chroma_offset_idx
] : 256;
70 m_chromaDistWeight
[1] = lambdaOffset
;
73 void setLambda(double lambda2
, double lambda
)
75 m_lambda2
= (uint64_t)floor(256.0 * lambda2
);
76 m_lambda
= (uint64_t)floor(256.0 * lambda
);
79 inline uint64_t calcRdCost(uint32_t distortion
, uint32_t bits
) const
81 X265_CHECK(bits
<= (UINT64_MAX
- 128) / m_lambda2
,
82 "calcRdCost wrap detected dist: %u, bits %u, lambda: "X265_LL
"\n", distortion
, bits
, m_lambda2
);
83 return distortion
+ ((bits
* m_lambda2
+ 128) >> 8);
86 /* return the difference in energy between the source block and the recon block */
87 inline int psyCost(int size
, const pixel
* source
, intptr_t sstride
, const pixel
* recon
, intptr_t rstride
) const
89 return primitives
.psy_cost_pp
[size
](source
, sstride
, recon
, rstride
);
92 /* return the difference in energy between the source block and the recon block */
93 inline int psyCost(int size
, const int16_t* source
, intptr_t sstride
, const int16_t* recon
, intptr_t rstride
) const
95 return primitives
.psy_cost_ss
[size
](source
, sstride
, recon
, rstride
);
98 /* return the RD cost of this prediction, including the effect of psy-rd */
99 inline uint64_t calcPsyRdCost(uint32_t distortion
, uint32_t bits
, uint32_t psycost
) const
101 return distortion
+ ((m_lambda
* m_psyRd
* psycost
) >> 16) + ((bits
* m_lambda2
) >> 8);
104 inline uint64_t calcRdSADCost(uint32_t sadCost
, uint32_t bits
) const
106 X265_CHECK(bits
<= (UINT64_MAX
- 128) / m_lambda
,
107 "calcRdSADCost wrap detected dist: %u, bits %u, lambda: "X265_LL
"\n", sadCost
, bits
, m_lambda
);
108 return sadCost
+ ((bits
* m_lambda
+ 128) >> 8);
111 inline uint32_t scaleChromaDist(uint32_t plane
, uint32_t dist
) const
113 X265_CHECK(dist
<= (UINT64_MAX
- 128) / m_chromaDistWeight
[plane
- 1],
114 "scaleChromaDist wrap detected dist: %u, lambda: %u\n", dist
, m_chromaDistWeight
[plane
- 1]);
115 return (uint32_t)((dist
* (uint64_t)m_chromaDistWeight
[plane
- 1] + 128) >> 8);
118 inline uint32_t getCost(uint32_t bits
) const
120 return (uint32_t)((bits
* m_lambda
+ 128) >> 8);
125 #endif // ifndef X265_TCOMRDCOST_H