diff options
author | dynaflash <[email protected]> | 2008-02-27 16:32:15 +0000 |
---|---|---|
committer | dynaflash <[email protected]> | 2008-02-27 16:32:15 +0000 |
commit | 818c2cf0e27b914bb031fc5ee00bd3f80a29b497 (patch) | |
tree | c72fc935e3174630628bb19b78ebd6a1b083c830 /contrib | |
parent | ed5556d6bc9f5f7c22a1068f55867881df046869 (diff) |
Adds Dark_Shikari's vbv 1 pass patch for x264
- While not optimal by any means according to Dark_Shikari over at x264, it definitely seems to help with the borked I frames we have been seeing using vbv 1 pass over x264 standard vbv.
- Rumors are that a more comprehensive fix is in the works for x264. But who wants to hold their breath. HB presets rely on vbv too much to have squashed I frames in the meantime.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1319 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/Jamfile | 3 | ||||
-rw-r--r-- | contrib/patch-x264-vbv-1pass.patch | 107 |
2 files changed, 109 insertions, 1 deletions
diff --git a/contrib/Jamfile b/contrib/Jamfile index 5bdcd3518..262ed0b0c 100644 --- a/contrib/Jamfile +++ b/contrib/Jamfile @@ -348,8 +348,9 @@ rule LibX264 { LIBX264_PATCH += " $(PATCH) -p1 < ../patch-x264-solaris.patch && " ; } -# AQ is temporarily disabled LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-aq.patch && " ; + # AQ is temporarily disabled LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-aq.patch && " ; LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-idr.patch && " ; + LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-vbv-1pass.patch && " ; LIBX264_PATCH += "$(PATCH) -p0 < ../patch-x264-vbv-2pass.patch && " ; Depends $(<) : $(>) ; Depends lib : $(<) ; diff --git a/contrib/patch-x264-vbv-1pass.patch b/contrib/patch-x264-vbv-1pass.patch new file mode 100644 index 000000000..fba885212 --- /dev/null +++ b/contrib/patch-x264-vbv-1pass.patch @@ -0,0 +1,107 @@ +Index: encoder/ratecontrol.c +=================================================================== +--- encoder/ratecontrol.c (revision 736) ++++ encoder/ratecontrol.c (working copy) +@@ -762,6 +899,15 @@ + return bits; + } + ++double row_bits_so_far( x264_t *h, int y ) ++{ ++ int i; ++ double bits = 0; ++ for( i = 0; i <= y; i++ ) ++ bits += h->fdec->i_row_bits[i]; ++ return bits; ++} ++ + void x264_ratecontrol_mb( x264_t *h, int bits ) + { + x264_ratecontrol_t *rc = h->rc; +@@ -783,10 +929,10 @@ + /* B-frames shouldn't use lower QP than their reference frames */ + if( y < h->sps->i_mb_height-1 ) + { +- rc->qpm = X264_MAX( rc->qp, +- X264_MIN( h->fref0[0]->i_row_qp[y+1], +- h->fref1[0]->i_row_qp[y+1] )); ++ int avg_qp = (h->fref0[0]->i_row_qp[y+1]+h->fref1[0]->i_row_qp[y+1])*0.5+rc->pb_offset * ((h->fenc->i_type == X264_TYPE_BREF) ? 0.5 : 1); ++ rc->qpm = X264_MAX( rc->qp, avg_qp); + } ++ //printf("Frame: %d QP: %d PrevQP: %d NextQP: %d NewQP: %d\n",h->i_frame,rc->qp,h->fref0[0]->i_row_qp[y+1],h->fref1[0]->i_row_qp[y+1],rc->qpm); + } + else + { +@@ -800,13 +946,47 @@ + int b1 = b0; + int i_qp_max = X264_MIN( prev_row_qp + h->param.rc.i_qp_step, h->param.rc.i_qp_max ); + int i_qp_min = X264_MAX( prev_row_qp - h->param.rc.i_qp_step, h->param.rc.i_qp_min ); +- float buffer_left_planned = rc->buffer_fill - rc->frame_size_planned; ++ float actual_size_planned = rc->frame_size_planned; ++ /* Don't modify the row QPs until a suffient amount of the bits of the frame have been processed, in case a flat */ ++ /* area at the top of the frame was measured inaccurately. */ ++ if(row_bits_so_far(h,y) < 0.15 * actual_size_planned) ++ { ++ return; ++ } ++ /* If this frame is a P-frame, make sure it isn't too large. */ ++ if(h->sh.i_type != SLICE_TYPE_I) ++ { ++ /*if(actual_size_planned > 2 * rc->buffer_rate) ++ { ++ float min_size = 2 * rc->buffer_rate; ++ actual_size_planned *= powf(min_size/actual_size_planned,0.8); ++ }*/ ++ } ++ /* If this frame is an I-frame and isn't too large, don't run the rest of row MBRC */ ++ else if(b1 < rc->buffer_fill * 0.6) ++ { ++ /* If the current row is higher QP than the frame QP, try lowering the QP */ ++ if(h->fdec->i_row_qp[0] < rc->qpm) ++ { ++ while(b1 < rc->buffer_fill * 0.6 && rc->qpm > h->fdec->i_row_qp[0]) ++ { ++ rc->qpm--; ++ b1 = predict_row_size_sum( h, y, rc->qpm ); ++ } ++ return; ++ } ++ else ++ return; ++ } ++ /* Don't let I-frames take up more than 60% of the remaining buffer. */ ++ else actual_size_planned = rc->buffer_fill * 0.6; ++ float buffer_left_planned = rc->buffer_fill - actual_size_planned; + + if( !rc->b_vbv_min_rate ) + i_qp_min = X264_MAX( i_qp_min, h->sh.i_qp ); + + while( rc->qpm < i_qp_max +- && (b1 > rc->frame_size_planned * 1.15 ++ && (b1 > actual_size_planned * 1.15 + || (rc->buffer_fill - b1 < buffer_left_planned * 0.5))) + { + rc->qpm ++; +@@ -814,8 +994,8 @@ + } + + while( rc->qpm > i_qp_min +- && buffer_left_planned > rc->buffer_size * 0.4 +- && ((b1 < rc->frame_size_planned * 0.8 && rc->qpm <= prev_row_qp) ++ && ((buffer_left_planned > rc->buffer_size * 0.4) || rc->qpm > h->fdec->i_row_qp[0]) ++ && ((b1 < actual_size_planned * 0.8 && rc->qpm <= prev_row_qp) + || b1 < (rc->buffer_fill - rc->buffer_size + rc->buffer_rate) * 1.1) ) + { + rc->qpm --; +@@ -1191,8 +1373,8 @@ + ( pict_type == SLICE_TYPE_P || + ( pict_type == SLICE_TYPE_I && rcc->last_non_b_pict_type == SLICE_TYPE_I ) ) ) + { +- if( rcc->buffer_fill/rcc->buffer_size < 0.5 ) +- q /= x264_clip3f( 2.0*rcc->buffer_fill/rcc->buffer_size, 0.5, 1.0 ); ++ float filled = 1.0 - rcc->buffer_fill/rcc->buffer_size; ++ q *= (1/0.544331054) / pow(2 - filled,1.5); + } + + if( rcc->b_vbv && rcc->last_satd > 0 ) + |