Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
12th June 2009, 19:35 | #1 | Link |
Wewkiee
Join Date: Feb 2002
Location: kashyyyk
Posts: 2,269
|
open-gop patch for x264 (committed)
I hacked up a open gop patch. all it really does is change the idr interval higher and force i-frames in at the max-keyint and flag them as recovery points. then clears the reference list of all frames behind the i when the first non-b is ready to be encoded. So for the most part it just interferes with frame decisioning a little and does some reference maintenance. x264 already supported i (small i) frames so it was fairly easy.
in a very few tests i get about 1.5% smaller size. thats with both at b-adapt 1(x264 default). B-adapt 2 with open-gop gives 4% improvement over a closed gop encode at b-adapt 1 and 5% over b-adapt 2 with closed-gop. fades seem to do well bitrate wise also. This patch really is only useful if you have small gops (ie bluray) . my tests were at min keyint of 12. This patch is not for your production encodes as it is experimental. Do not create any binaries with this patch that may be in automatic upgrading scripts to protect the innocent. there will be 2 attachments. one is the patch by itself and one with hrd(interlaced) 13 patch on top of it (as hrd has to be adjusted to open gop and also the patches update the same part of encoder.c ). this hrd version does not replace the current hrd patch. again both are experimental
__________________
...yeah...but...why on earth would I compare apples with apples? Last edited by Trahald; 27th June 2010 at 12:28. |
12th June 2009, 20:03 | #2 | Link | |
x264 developer
Join Date: Sep 2005
Posts: 8,666
|
Quote:
|
|
13th June 2009, 05:45 | #3 | Link |
Wewkiee
Join Date: Feb 2002
Location: kashyyyk
Posts: 2,269
|
yessir. my thought was that max keyint is some arbitrary thing, but a scenecut is x264 saying a key frame is needed here (re:quality). i plan to go back in and look for more cases where open gop makes sense.
__________________
...yeah...but...why on earth would I compare apples with apples? Last edited by Trahald; 13th June 2009 at 05:51. |
23rd June 2009, 18:22 | #7 | Link |
Wewkiee
Join Date: Feb 2002
Location: kashyyyk
Posts: 2,269
|
This is an experimental build with Open GOP for those that want to play w/it.
http://www.mediafire.com/file/4muyzw...71_opengop.zip fprofiled x264_open_gop_hrd.2.diff x264_win_zone_parse_fix_05.diff x264_AutoVAQ.03.diff
__________________
...yeah...but...why on earth would I compare apples with apples? |
23rd June 2009, 18:36 | #8 | Link | |
Registered User
Join Date: Mar 2006
Posts: 1,538
|
Quote:
|
|
23rd June 2009, 21:39 | #11 | Link | ||||
BluRay Maniac
Join Date: Dec 2005
Posts: 2,419
|
@Trahald, thanks for patch and experimental build, results are more than expected
With Open GOP Quote:
Quote:
Quote:
Quote:
and I have to ask how this patch is far from the final version because work perfectly Last edited by shon3i; 23rd June 2009 at 21:41. |
||||
23rd June 2009, 22:01 | #12 | Link |
x264 developer
Join Date: Sep 2005
Posts: 8,666
|
Patch review for open-GOP patch.
1. Use spaces, not tabs. I don't want to have to correct this for you. 2. Use consistent style. x264 puts the bracket on the next line, not the same line as the if statement. 3. What is this? Code:
if( h->param.b_open_gop && h->param.i_keyint_max < 250 ) { //using default as cutoff h->param.i_keyint_max = 250; } 4. Don't add extra spaces for no reason: Code:
@@ -1472,9 +1479,17 @@ int x264_encoder_encode( x264_t *h, return 0; } + if( h->fenc->i_type == X264_TYPE_IDR ) Code:
+ if( frames[1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[1]->i_type = X264_TYPE_I; + frames[1]->i_is_gop_start = 1; + return; + } + if( num_frames == 1 ) { no_b_frames: frames[1]->i_type = X264_TYPE_P; + if( frames[1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[1]->i_type = X264_TYPE_I; + frames[1]->i_is_gop_start = 2; + return; + } if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, 0, 1 ) ) frames[1]->i_type = idr_frame_type; return; @@ -516,6 +530,12 @@ no_b_frames: { int num_bframes; int max_bframes = X264_MIN(num_frames-1, h->param.i_bframe); + if( frames[1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[1]->i_type = X264_TYPE_I; + frames[1]->i_is_gop_start = 3; + return; + } if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, 0, 1 ) ) { frames[1]->i_type = idr_frame_type; @@ -526,6 +546,12 @@ no_b_frames: for( j = 1; j < num_bframes+1; j++ ) { + if( frames[j]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[j]->i_type = X264_TYPE_I; + frames[j]->i_is_gop_start = 4; + return; + } if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, j, j+1 ) ) { frames[j]->i_type = X264_TYPE_P; @@ -533,6 +559,12 @@ no_b_frames: } frames[j]->i_type = X264_TYPE_B; } + if( frames[num_bframes+1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[num_bframes+1]->i_type = X264_TYPE_I; + frames[num_bframes+1]->i_is_gop_start = 5; + return; + } frames[num_bframes+1]->i_type = X264_TYPE_P; } else if( h->param.i_bframe_adaptive == X264_B_ADAPT_FAST ) @@ -552,12 +584,22 @@ no_b_frames: #define INTER_THRESH 300 #define P_SENS_BIAS (50 - h->param.i_bframe_bias) frames[1]->i_type = X264_TYPE_B; - + if( frames[1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[1]->i_type = X264_TYPE_I; + frames[1]->i_is_gop_start = 6; + return; + } for( j = 2; j <= X264_MIN( h->param.i_bframe, num_frames-1 ); j++ ) { int pthresh = X264_MAX(INTER_THRESH - P_SENS_BIAS * (j-1), INTER_THRESH/10); int pcost = x264_slicetype_frame_cost( h, &a, frames, 0, j+1, j+1, 1 ); - + if( frames[j]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[j]->i_type = X264_TYPE_I; + frames[j]->i_is_gop_start = 7; + return; + } if( pcost > pthresh*i_mb_count || frames[j+1]->i_intra_mbs[j+1] > i_mb_count/3 ) { frames[j]->i_type = X264_TYPE_P; @@ -570,6 +612,12 @@ no_b_frames: else { int max_bframes = X264_MIN(num_frames-1, h->param.i_bframe); + if( frames[1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[1]->i_type = X264_TYPE_I; + frames[1]->i_is_gop_start = 8; + return; + } if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, 0, 1 ) ) { frames[1]->i_type = idr_frame_type; @@ -578,6 +626,12 @@ no_b_frames: for( j = 1; j < max_bframes+1; j++ ) { + if( frames[j]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[j]->i_type = X264_TYPE_I; + frames[j]->i_is_gop_start = 9; + return; + } if( h->param.i_scenecut_threshold && scenecut( h, &a, frames, j, j+1 ) ) { frames[j]->i_type = X264_TYPE_P; @@ -585,6 +639,12 @@ no_b_frames: } frames[j]->i_type = X264_TYPE_B; } + if( frames[max_bframes+1]->i_frame - h->frames.i_last_i >= h->param.i_keyint_max_i && h->param.b_open_gop ) + { + frames[max_bframes+1]->i_type = X264_TYPE_I; + frames[max_bframes+1]->i_is_gop_start = 10; + return; + } frames[max_bframes+1]->i_type = X264_TYPE_P; } } 6. Why do we have two parameters that do the same thing? Code:
int i_keyint_max; /* Force an IDR keyframe at this interval */ + int i_keyint_max_i; |
24th June 2009, 04:56 | #13 | Link |
Wewkiee
Join Date: Feb 2002
Location: kashyyyk
Posts: 2,269
|
@Dark Shikari
1,2 & 4 . the only cleanup i did was to remove fprintf's. I'll take care of that stuff tho 3 & 6. when open_gop is true then i_keyint_max ends up meaning (max IDR interval) which i push to 250 unless its value is higher. i_keyint_max_i represents the interval of little i frames. So... i_keyint_max_i = i_keyint_max; // the users input i_keyint_max = i_keyint_max > 250 ? i_keyint_max : 250; 5. yeah yuck. thats me throwing spaghetti at the wall and seeing what sticks. i'll work on it. the multiple values thing was more for debugging but since its harmless i left it.
__________________
...yeah...but...why on earth would I compare apples with apples? Last edited by Trahald; 24th June 2009 at 04:59. |
24th June 2009, 05:04 | #14 | Link | |
x264 developer
Join Date: Sep 2005
Posts: 8,666
|
Quote:
When someone says they want a keyframe interval of 90 frames, they mean they want a keyframe every 90 frames; an open-GOP I-frame is still a keyframe, so that counts. Yes, we'll have to redefine what i_keyint_max does in the documentation to not literally say "IDR." If, for technical reasons, we still need to force IDR frames every once in a while despite open-GOPs being perfectly fine keyframes, the value should be really large. |
|
24th June 2009, 23:38 | #15 | Link | |
Wewkiee
Join Date: Feb 2002
Location: kashyyyk
Posts: 2,269
|
Quote:
1. anyplace there is a max_keyint referenced that relates to scenecut, replace w/integer 400000 when open gop is true 2. remove max_keyint from the scenecut routines (w/or w/out opengop) and do whatever keyint is used for there some other way
__________________
...yeah...but...why on earth would I compare apples with apples? Last edited by Trahald; 24th June 2009 at 23:40. |
|
24th June 2009, 23:40 | #16 | Link | |
x264 developer
Join Date: Sep 2005
Posts: 8,666
|
Quote:
Again, "max keyint" in scenecut routines should be the distance between keyframes, not the distance between IDR frames. |
|
25th June 2009, 01:29 | #17 | Link | ||
Wewkiee
Join Date: Feb 2002
Location: kashyyyk
Posts: 2,269
|
Quote:
Quote:
in either scenario, max_keyint_i is done away with and there is only max key int in scenarion 1. its a cosmetic removal as im just hardcoding the larger value. but.. this would code wise remove the extra value. max_keyint would be commented as maximum distance between IDR frames or Recovery points. OR scenario 2. here again, there is only one max_keyint . but here we remove any scenecut decisioning that relies on the distance between keyintervals, whatever that interval is. scenecuts in streams at max_keyint 24 would be in the same spots as streams with max_keyint 50, etc.
__________________
...yeah...but...why on earth would I compare apples with apples? |
||
25th June 2009, 02:01 | #18 | Link | |||
x264 developer
Join Date: Sep 2005
Posts: 8,666
|
Quote:
1. B-frame decision, in which this doesn't help, since you're still forced to end the GOP, even if it's on an open GOP. 2. Scenecut decision, in which what you are doing is outright lying to the scenecut algorithm about where the last keyframe actually was. I will not accept a patch that does this for any reason whatsoever. If you think that the scenecut algorithm is suboptimal, fix it separately. Quote:
Quote:
What is wrong with my original suggestion of just doing it the sensible way--leaving scenecut as it is, and treating all open GOPs as keyframes? Why do we have to munge the scenecut algorithm like this, independent of what your patch is actually doing? |
|||
25th June 2009, 04:52 | #19 | Link | |
Registered User
Join Date: Oct 2001
Location: Germany
Posts: 7,551
|
Quote:
|
|
Thread Tools | Search this Thread |
Display Modes | |
|
|