After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 621663 - x264enc: support changing bitrate property on the fly
x264enc: support changing bitrate property on the fly
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-ugly
git master
Other Linux
: Normal normal
: 0.10.18
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2010-06-15 16:12 UTC by Havoc Pennington
Modified: 2011-03-30 08:05 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
RFC: allow changing x264enc bitrate on the fly (2.27 KB, patch)
2010-06-15 17:45 UTC, Tommi Komulainen
needs-work Details | Review
x264enc: Make it clear that constant quantizer is for debugging only (1.04 KB, patch)
2010-09-22 01:11 UTC, Olivier Crête
committed Details | Review
x264enc: Set max bitrate in quality mode (1.62 KB, patch)
2010-09-22 01:12 UTC, Olivier Crête
committed Details | Review
x264enc: Allow changing the bitrate and quantitizers dynamically (5.24 KB, patch)
2010-09-22 01:12 UTC, Olivier Crête
none Details | Review
x264enc: Force frameref=1 if the intra-refresh is true (1.03 KB, patch)
2010-09-22 01:12 UTC, Olivier Crête
rejected Details | Review
Video encoded at 250k (740.00 KB, application/octet-stream)
2010-11-25 08:01 UTC, Ian Mitchell
  Details
Video encoded at an average of 250k (780.00 KB, application/octet-stream)
2010-11-25 08:11 UTC, Ian Mitchell
  Details
Video encoded at 250k (743.64 KB, application/octet-stream)
2010-11-25 09:19 UTC, Ian Mitchell
  Details
Video encoded at an average of 250k (797.50 KB, application/octet-stream)
2010-11-25 09:22 UTC, Ian Mitchell
  Details
x264enc: Allow changing the bitrate and quantitizers dynamically (4.96 KB, patch)
2011-01-05 19:54 UTC, Olivier Crête
committed Details | Review

Description Havoc Pennington 2010-06-15 16:12:53 UTC
In particular would like to change "bitrate" on the fly. If you set this property after gst_x264_enc_init_encoder() it just silently does nothing though.
(Sets encoder->bitrate but does not pass it on to x264)

I don't know if this is an x264 limitation or just something unimplemented in x264enc.

Thoughts on how to patch this welcome
Comment 1 Havoc Pennington 2010-06-15 16:24:30 UTC
It looks like x264_encoder_reconfig() allows changing some but not all props on the fly. Bitrate can be changed if in VBV mode

    /* VBV can't be turned on if it wasn't on to begin with */
    if( h->param.rc.i_vbv_max_bitrate > 0 && h->param.rc.i_vbv_buffer_size > 0 &&
          param->rc.i_vbv_max_bitrate > 0 &&   param->rc.i_vbv_buffer_size > 0 )
    {
        COPY( rc.i_vbv_max_bitrate );
        COPY( rc.i_vbv_buffer_size );
        COPY( rc.i_bitrate );
        rc_reconfig = 1;
    }

Anyway either setting a prop could immediately reconfig, I guess, or x264enc could have some kind of "need reconfig" flag that it handles on the next buffer?
Comment 2 Tommi Komulainen 2010-06-15 17:45:20 UTC
Created attachment 163706 [details] [review]
RFC: allow changing x264enc bitrate on the fly

Seems to have noticeable visual impact on quality when decreased (to very low) from configured value. Configuring the pipeline to low bitrate and then increasing the value doesn't improve the quality as much as it should.
Comment 3 Tim-Philipp Müller 2010-08-06 12:15:54 UTC
This sounds like a nice thing to support. FWIW, we now have GST_PARAM_MUTABLE_PLAYING with which properties that can be updated during playing state can be marked.

Patch needs updating after recent x264enc changes.
Comment 4 Jason Garrett-Glaser 2010-08-10 22:55:17 UTC
Specifically, x264 lets you do one of three things:

1.  In CBR mode, you can change the bitrate.  You cannot go out of CBR mode if you started there.  Thus, you must change maxrate and bitrate together, keeping them equal.  You probably want to change bufsize too, depending on the application.

2.  In CRF mode, you can change the CRF.

3.  In any mode with VBV active, you can change the maxrate and bufsize.  However, if you started in CBR (per 1), you must stay in CBR.

In short, you can modify CRF, maxrate, and bufsize arbitrarily, but you cannot change ratecontrol modes (where the available modes are CBR, ABR, and CRF).
Comment 5 Olivier Crête 2010-09-22 01:11:45 UTC
Created attachment 170801 [details] [review]
x264enc: Make it clear that constant quantizer is for debugging only

That's what Jason told me on IRC.
Comment 6 Olivier Crête 2010-09-22 01:12:08 UTC
Created attachment 170802 [details] [review]
x264enc: Set max bitrate in quality mode

The maximum bitrate can be set in that case too, its probably what
we want most of the time.
Comment 7 Olivier Crête 2010-09-22 01:12:23 UTC
Created attachment 170803 [details] [review]
x264enc: Allow changing the bitrate and quantitizers dynamically
Comment 8 Olivier Crête 2010-09-22 01:12:34 UTC
Created attachment 170804 [details] [review]
x264enc: Force frameref=1 if the intra-refresh is true

If it is not forced to 1, x264 will print a warning and set
it to 1 anyway.
Comment 9 Olivier Crête 2010-09-22 01:27:19 UTC
as for the lowered quality when you switch bitrate, if you do it slowly instead of in big jumps, it doesn't happen.
Comment 10 Jason Garrett-Glaser 2010-09-22 21:41:01 UTC
Don't force ref=1 for intra-refresh; in the future, x264 may add support for multiref + intra refresh.  It's not conceptually wrong.
Comment 11 Olivier Crête 2010-09-23 03:21:12 UTC
Comment on attachment 170804 [details] [review]
x264enc: Force frameref=1 if the intra-refresh is true

Jason, ok thanks for the info, please don't make it a warning then!
Comment 12 Jason Garrett-Glaser 2010-09-23 03:34:51 UTC
Those statements seem completely irrelevant to me.  x264 currently doesn't implement X + Y.  It may one day implement X + Y.  What's wrong with telling the user in the meantime that it doesn't?
Comment 13 Olivier Crête 2010-09-23 03:40:37 UTC
was making the user (me) think he was doing something wrong
Comment 14 Ian Mitchell 2010-11-24 16:26:13 UTC
Hi,

I wrote a simple test routine in h264 to see if a constant 250kb rate encoded stream had the same quality and size as a stream with an average rate of 250kb(every 50 frames it changed between 350kb and 150kb to average at 250kb, there are 600 frames in the file).

The file for the average case had a slightly lower PNSR but much larger file size.

Has anybody else tried this before?

Thanks,

Ian
Comment 15 Jason Garrett-Glaser 2010-11-24 20:03:18 UTC
Can you post your two output samples?
Comment 16 Ian Mitchell 2010-11-25 08:01:08 UTC
Created attachment 175220 [details]
Video encoded at 250k
Comment 17 Ian Mitchell 2010-11-25 08:11:04 UTC
Created attachment 175221 [details]
Video encoded at an average of 250k

The constant bitrate stream.
----------------------------

The arguments are:

--threads 1 --rc-lookahead 0 --no-psy --bitrate 250 --vbv-maxrate 250 --vbv-bufsize 250 --psnr --input-res 352x288 -b 0 --no-scenecut --no-progress -i 25 -I 25 -o video1 /devel/statmux/rawvid/quadforeman_cif

The average stream.
-------------------

Once each frame is encoded(from x264_encoder_frame_end in encoder.c) this is called:

		if( (frameCount % 50) == 0 )
		{
			int newBitrate;

			if( test_args[0].bitrate == 350)
			{
				newBitrate = 150;
			}
			else
			{
				newBitrate = 350;
			}

			for( i=0 ; i < NO_ENCODERS ; i++ )
			{
				set_bitrate( i, newBitrate );
			}
		}

The workings of the set_bitrate function are:

x264_encoder_parameters( test_args[encoderIndex].handle , &param );
	param.rc.i_bitrate = bitrate;
	param.rc.i_vbv_max_bitrate = bitrate;
	param.rc.i_vbv_buffer_size = bitrate; /* the size = bitrate x delay, say 1 second delay at the moment so bitrate = buffer size */

	if( (ret = x264_encoder_reconfig( test_args[encoderIndex].handle, &param)) != 0 )
	{
Comment 18 Jason Garrett-Glaser 2010-11-25 08:27:28 UTC
And the x264 log output with PSNR and other info?
Comment 19 Ian Mitchell 2010-11-25 08:38:00 UTC
For the constant bitrate one:

x264 [info]: frame I:24    Avg QP:34.84  size:  7949  PSNR Mean Y:30.14 U:38.52 V:40.00 Avg:31.63 Global:31.59
x264 [info]: frame P:576   Avg QP:37.78  size:   992  PSNR Mean Y:28.06 U:38.10 V:39.67 Avg:29.64 Global:29.60
x264 [info]: mb I  I16..4: 14.2% 55.3% 30.6%
x264 [info]: mb P  I16..4:  0.5%  0.3%  0.2%  P16..4: 38.0% 11.9%  3.7%  0.0%  0.0%    skip:45.4%
x264 [info]: 8x8 transform intra:50.3% inter:61.7%
x264 [info]: coded y,uvDC,uvAC intra: 80.5% 40.3% 12.3% inter: 13.0% 3.3% 0.1%
x264 [info]: i16 v,h,dc,p: 18% 38% 34% 11%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 22% 28% 20%  4%  4%  4%  5%  4%  8%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 35% 15%  3%  4%  3%  4%  3%  4%
x264 [info]: i8c dc,h,v,p: 71% 20%  7%  2%
x264 [info]: Weighted P-Frames: Y:0.7%
x264 [info]: ref P L0: 69.7% 17.3%  9.4%  3.4%  0.1%
x264 [info]: PSNR Mean Y:28.138 U:38.121 V:39.687 Avg:29.716 Global:29.661 kb/s:254.07

encoded[1] 600 frames, 33.34 fps, 254.07 kb/s

And for the average bitrate one:

x264 [info]: frame I:24    Avg QP:32.18  size: 10738  PSNR Mean Y:32.16 U:39.16 V:40.86 Avg:33.57 Global:33.54
x264 [info]: frame P:576   Avg QP:35.34  size:  1406  PSNR Mean Y:29.66 U:38.57 V:40.35 Avg:31.20 Global:31.16
x264 [info]: mb I  I16..4: 10.5% 55.4% 34.2%
x264 [info]: mb P  I16..4:  0.4%  0.3%  0.3%  P16..4: 38.6% 15.3%  6.3%  0.0%  0.0%    skip:39.0%
x264 [info]: 8x8 transform intra:51.0% inter:57.8%
x264 [info]: coded y,uvDC,uvAC intra: 86.7% 47.9% 17.8% inter: 17.8% 4.6% 0.1%
x264 [info]: i16 v,h,dc,p: 19% 38% 34% 10%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 20% 27% 19%  5%  5%  4%  6%  5% 10%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 27% 36% 13%  3%  4%  3%  4%  4%  5%
x264 [info]: i8c dc,h,v,p: 62% 25% 11%  3%
x264 [info]: Weighted P-Frames: Y:0.7%
x264 [info]: ref P L0: 67.8% 18.4%  9.8%  3.8%  0.1%
x264 [info]: PSNR Mean Y:29.763 U:38.591 V:40.374 Avg:31.291 Global:31.230 kb/s:355.83

encoded[1] 600 frames, 29.77 fps, 355.83 kb/s
Comment 20 Jason Garrett-Glaser 2010-11-25 09:03:20 UTC
$ ls -l video*
-rwx------+ 1 Administrators None 757760 2010-11-25 01:02 video250k
-rwx------+ 1 Administrators None 798720 2010-11-25 01:02 videoavg250k

I highly doubt these files match up to the logs you just posted.
Comment 21 Ian Mitchell 2010-11-25 09:19:08 UTC
Created attachment 175228 [details]
Video encoded at 250k

My bad! a replacement file, the average and logs to come...
Comment 22 Ian Mitchell 2010-11-25 09:22:38 UTC
Created attachment 175229 [details]
Video encoded at an average of 250k

Log for the constant 250k bitrate:

x264 [info]: frame I:24    Avg QP:27.43  size:  7548  PSNR Mean Y:37.04 U:41.15 V:43.41 Avg:38.17 Global:37.90
x264 [info]: frame P:576   Avg QP:30.57  size:  1008  PSNR Mean Y:35.01 U:40.32 V:42.23 Avg:36.26 Global:36.02
x264 [info]: mb I  I16..4: 16.2% 44.0% 39.8%
x264 [info]: mb P  I16..4:  1.3%  1.8%  0.3%  P16..4: 40.4% 12.0%  3.2%  0.0%  0.0%    skip:41.0%
x264 [info]: 8x8 transform intra:48.4% inter:69.3%
x264 [info]: coded y,uvDC,uvAC intra: 62.8% 51.6% 18.1% inter: 14.2% 7.5% 0.3%
x264 [info]: i16 v,h,dc,p: 29% 23% 23% 24%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 14% 16% 21%  4% 11%  9% 10%  6%  8%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 14% 14% 21%  4% 20%  7%  9%  3%  9%
x264 [info]: i8c dc,h,v,p: 57% 20% 18%  5%
x264 [info]: Weighted P-Frames: Y:0.3%
x264 [info]: ref P L0: 65.2% 21.1% 10.0%  3.7%  0.0%
x264 [info]: PSNR Mean Y:35.090 U:40.352 V:42.276 Avg:36.339 Global:36.086 kb/s:253.83

encoded[0] 600 frames, 76.99 fps, 253.83 kb/s

Log for the 25k average bitrate:

x264 [info]: frame I:24    Avg QP:30.11  size:  6419  PSNR Mean Y:35.44 U:40.39 V:42.40 Avg:36.65 Global:35.79
x264 [info]: NULL handle!
Average PSNR for encoder 0 is 36.059 frame #600, total bits so far 816642
Average PSNR for encoder 1 is 0.000 frame #600, total bits so far 0
frame P:576   Avg QP:30.73  size:  1150  PSNR Mean Y:34.78 U:40.11 V:41.97 Avg:36.03 Global:35.43
x264 [info]: mb I  I16..4: 18.6% 49.7% 31.7%
x264 [info]: mb P  I16..4:  1.4%  1.7%  0.3%  P16..4: 41.4% 12.8%  4.4%  0.0%  0.0%    skip:38.0%
x264 [info]: 8x8 transform intra:50.1% inter:65.2%
x264 [info]: coded y,uvDC,uvAC intra: 54.9% 47.9% 17.2% inter: 16.1% 9.1% 0.4%
x264 [info]: i16 v,h,dc,p: 32% 26% 21% 22%
x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 14% 14% 24%  4% 12%  9% 10%  6%  8%
x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 13% 13% 23%  4% 19%  7%  9%  3%  8%
x264 [info]: i8c dc,h,v,p: 63% 17% 16%  4%
x264 [info]: Weighted P-Frames: Y:0.3%
x264 [info]: ref P L0: 65.6% 18.9% 11.3%  4.2%  0.0%
x264 [info]: PSNR Mean Y:34.809 U:40.124 V:41.986 Avg:36.059 Global:35.444 kb/s:272.21

encoded[0] 600 frames, 72.73 fps, 272.21 kb/s

I was in a rush and got it wrong, sorry about that, these are the correct files and logs.
Comment 23 Jason Garrett-Glaser 2010-11-25 10:07:56 UTC
What's your problem then?  The constant bitrate (as expected) has higher PSNR.
Comment 24 Ian Mitchell 2010-11-25 10:11:15 UTC
Why is a higher PSNR expected from a stream that is encoded at 250k than a steam that has an average requested rate of 250k?
Comment 25 Jason Garrett-Glaser 2010-11-25 10:26:40 UTC
If you change the bitrate between 150k and 350k constantly, you will get worse quality than if you left it at 250k for the whole encode.  This isn't blazingly obvious?!!
Comment 26 Ian Mitchell 2010-11-25 10:38:12 UTC
To be honest, its not obvious to me, I apologise for my lack of understanding. If you have the time, please can you explain why you'd expect a lower quality? I can comprehend that there could be a quality penalty in if you change the bitrate but I don't exactly know why that'd happen.

Leaving the quality aside, why would the overall bitrate be different? The requested bitrate averages at 250k. Do you think the encoder rate controller reacts to a bitrate increase quicker than a decrease? I'm not sure what is going on here.

Thanks for your help.
Comment 27 Jason Garrett-Glaser 2010-11-25 11:06:03 UTC
The overall bitrate is different because your video is short and the difference in VBV states is sufficient to account for the difference.

A drop in bitrate hurts PSNR more than a rise in bitrate helps PSNR.  Thus, artificially dropping bitrate for a part of the video (and boosting it for another) will generally hurt overall PSNR.
Comment 28 Ian Mitchell 2010-11-25 11:26:35 UTC
I can understand the quality, that makes sense to me, thanks.

However I'm not quite sure of the size difference being due to the VBV buffer size because the buffer size(on average) is the same. But this helps me, I will spend more time understanding the buffer size effect. Maybe I shouldn't one to one map it with bitrate, I did that because I assumed that a buffer that could hold one seconds worth of data would be sufficient, maybe the buffer should stay constant. I'll experiment.

Thanks for you help, it is much appreciated.
Comment 29 Olivier Crête 2011-01-05 19:54:35 UTC
Created attachment 177609 [details] [review]
x264enc: Allow changing the bitrate and quantitizers dynamically

Updated patch to match master.. Any chance some can review/merge this ?
Comment 30 Olivier Crête 2011-02-19 02:43:56 UTC
ping ?
Comment 31 Tim-Philipp Müller 2011-03-29 21:50:09 UTC
Comment on attachment 177609 [details] [review]
x264enc: Allow changing the bitrate and quantitizers dynamically

Looks fine to me.

>   state = GST_STATE (encoder);
>-  if (state != GST_STATE_READY && state != GST_STATE_NULL)
>+  if ((state != GST_STATE_READY && state != GST_STATE_NULL) &&
>+      !(pspec->flags & GST_PARAM_MUTABLE_PLAYING))
>     goto wrong_state;

(Nitpick: I guess & (MUTABLE_PLAYING | MUTABLE_PAUSED) would be more correct, but it doesn't matter currently, and is unlikely to ever matter, since PAUSED vs. PLAYING behaviour is the same for an encoder, so MUTABLE_PAUSED doesn't make sense)..
Comment 32 Olivier Crête 2011-03-30 00:13:59 UTC
MUTABLE_PLAYING includes PAUSED & READY.. see:

http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstParamSpec.html#GST-PARAM-MUTABLE-PLAYING:CAPS



commit 62e35a6b40feb7bb5d080cd2660b4ebe8fb107d6
Author: Olivier Crête <olivier.crete@collabora.co.uk>
Date:   Tue Sep 21 20:14:04 2010 -0400

    x264enc: Allow changing the bitrate and quantitizers dynamically
    
    https://bugzilla.gnome.org/show_bug.cgi?id=621663

commit a4df8f90310ddfb7997d19435ced80a3b4902e74
Author: Olivier Crête <olivier.crete@collabora.co.uk>
Date:   Tue Sep 21 19:33:10 2010 -0400

    x264enc: Set max bitrate in quality mode
    
    https://bugzilla.gnome.org/show_bug.cgi?id=621663

commit 1370f3f161ff36d0e31f65dae5c7efed5a6f6648
Author: Olivier Crête <olivier.crete@collabora.co.uk>
Date:   Tue Sep 21 19:20:29 2010 -0400

    x264enc: Make it clear that constant quantizer is for debugging only
    
    https://bugzilla.gnome.org/show_bug.cgi?id=621663
Comment 33 Tim-Philipp Müller 2011-03-30 08:05:29 UTC
> MUTABLE_PLAYING includes PAUSED & READY.. see:

What I meant was that the check would fail with MUTABLE_PAUSED properties (but there aren't any atm, so..)