[x264-devel] commit: Smarter QPRD (Jason Garrett-Glaser )
git version control
git at videolan.org
Mon Feb 15 10:20:21 CET 2010
x264 | branch: master | Jason Garrett-Glaser <darkshikari at gmail.com> | Wed Feb 3 20:01:16 2010 -0800| [346165169775c5884a9e964afc253561bb11e2ca] | committer: Jason Garrett-Glaser
Smarter QPRD
Catch some cases in which RD checks can be avoided; reduces QPRD RD calls by 10-20%.
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=346165169775c5884a9e964afc253561bb11e2ca
---
encoder/analyse.c | 42 ++++++++++++++++++++++++++++++++++++++----
1 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/encoder/analyse.c b/encoder/analyse.c
index c15bf8f..1d48b7d 100644
--- a/encoder/analyse.c
+++ b/encoder/analyse.c
@@ -2307,9 +2307,10 @@ static inline void x264_mb_analyse_qp_rd( x264_t *h, x264_mb_analysis_t *a )
int orig_qp = h->mb.i_qp, bqp = h->mb.i_qp;
int last_qp_tried = 0;
origcost = bcost = x264_rd_cost_mb( h, a->i_lambda2 );
+ int origcbp = h->mb.cbp[h->mb.i_mb_xy];
/* If CBP is already zero, don't raise the quantizer any higher. */
- for( direction = h->mb.cbp[h->mb.i_mb_xy] ? 1 : -1; direction >= -1; direction-=2 )
+ for( direction = origcbp ? 1 : -1; direction >= -1; direction-=2 )
{
/* Without psy-RD, require monotonicity when moving quant away from previous
* macroblock's quant; allow 1 failure when moving quant towards previous quant.
@@ -2324,14 +2325,47 @@ static inline void x264_mb_analyse_qp_rd( x264_t *h, x264_mb_analysis_t *a )
h->mb.i_qp = orig_qp;
failures = 0;
prevcost = origcost;
+
+ /* If the current QP results in an empty CBP, it's highly likely that lower QPs
+ * (up to a point) will too. So, jump down to where the threshold will kick in
+ * and check the QP there. If the CBP is still empty, skip the main loop.
+ * If it isn't empty, we would have ended up having to check this QP anyways,
+ * so as long as we store it for later lookup, we lose nothing. */
+ int already_checked_qp = -1;
+ int already_checked_cost = COST_MAX;
+ if( direction == -1 )
+ {
+ if( !origcbp )
+ {
+ h->mb.i_qp = X264_MAX( h->mb.i_qp - threshold - 1, h->param.rc.i_qp_min );
+ h->mb.i_chroma_qp = h->chroma_qp_table[h->mb.i_qp];
+ already_checked_cost = x264_rd_cost_mb( h, a->i_lambda2 );
+ if( !h->mb.cbp[h->mb.i_mb_xy] )
+ {
+ /* If our empty-CBP block is lower QP than the last QP,
+ * the last QP almost surely doesn't have a CBP either. */
+ if( h->mb.i_last_qp > h->mb.i_qp )
+ last_qp_tried = 1;
+ break;
+ }
+ already_checked_qp = h->mb.i_qp;
+ h->mb.i_qp = orig_qp;
+ }
+ }
+
h->mb.i_qp += direction;
while( h->mb.i_qp >= h->param.rc.i_qp_min && h->mb.i_qp <= h->param.rc.i_qp_max )
{
if( h->mb.i_last_qp == h->mb.i_qp )
last_qp_tried = 1;
- h->mb.i_chroma_qp = h->chroma_qp_table[h->mb.i_qp];
- cost = x264_rd_cost_mb( h, a->i_lambda2 );
- COPY2_IF_LT( bcost, cost, bqp, h->mb.i_qp );
+ if( h->mb.i_qp == already_checked_qp )
+ cost = already_checked_cost;
+ else
+ {
+ h->mb.i_chroma_qp = h->chroma_qp_table[h->mb.i_qp];
+ cost = x264_rd_cost_mb( h, a->i_lambda2 );
+ COPY2_IF_LT( bcost, cost, bqp, h->mb.i_qp );
+ }
/* We can't assume that the costs are monotonic over QPs.
* Tie case-as-failure seems to give better results. */
More information about the x264-devel
mailing list