-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic bitrate change (H.264) #287
Comments
Normally, I'd consider the data type of the quantity (2000 in this case). g_object_set is not typesafe at compile time, since it uses C varargs, so I developed a habit of explicitly casting to match the type with the one from the GObject property, like this:
However - "2000" is an int, so it should not matter here.. I'll try it on my machine. |
I found out what's wrong. It was a bug in libimxvpuapi. See Freescale/libimxvpuapi@4c682f1 Can you test the latest libimxvpuapi git master? |
@dv1 thank you for looking into that. I'll try it next week (in fact will try to find some room next days but quite a few urgent things here). Looking on that patch - are you sure that OMX_Video_ControlRateVariable will produce CBR stream (constant bitrate stream) until next bitrate change request? (It is what I assumed to use) On first guess OMX_Video_ControlRateVariable should activate VBR (variable bitrate) rate control which usually tries to keep constant video quality, allowing stream bitrate fluctuations. Variable bitrate (when encoder decides to change video bitrate itself, not due to our request) will be problematic to us - we use some RF link (radio modems) to stream video and we can't afford the case when bitrate goes over link budget (and VBR is this case - we can't guarantee bitrate). Anyway - I'll test it on my side and get back to you. Thank you again! |
I am not sure if the encoder actually can do proper CBR. Even if I set it to "Constant", I do not notice significant differences in output buffer sizes. I am not sure though. Will check. |
Any results on your end? I unfortunately did not yet have the time to test the bitstream. In my last test, I again did not see meaningful differences between OMX_Video_ControlRateVariable and OMX_Video_ControlRateConstant modes. I suspect that the Hantro driver treats them mostly the same..? |
@dv1 sorry for delays - a lot of things happened here. I did the tests (very basic) today and as for me it looks quite adequate. Thank you for your support! I think it would take me ages to find such solution. |
Great :) Just one request if possible - can you run a basic test with OMX_Video_ControlRateConstant instead of OMX_Video_ControlRateVariable and let me know what differences you see, if any? Intuitively, it seems to me that OMX_Video_ControlRateConstant would be the "correct" choice, but as said, I see little actual difference. |
On first look OMX_Video_ControlRateVariable is more smooth on quantizer and probably does not drop frames (bitrate change is relatively smooth). OMX_Video_ControlRateConstant is more aggressive on keeping bitrate within some window. Perhaps OMX_Video_ControlRateVariable does averaging over longer window and is kind of ABR. But honestly - it is just guess - I looked on bitrate graph in Wireshark and that's all. I expect to get more time for my bitrate exercises later and most likely will have time to evaluate RD plots and compare them. BTW, do you plan to enhance encoder API a bit? It would be handy to be able to force key frame when we need that and to control RC buffer size together with IDR QP ratio (if we set relatively large GOP length encoder 'feels free' to allocate too much for IDR frame and we have bitrate burst - radio is not happy then). |
I'd be very happy to hear suggestions for how to enhance the encoding API, since I don't do much encoding and have no real-world hands-on experience in that regard. But - I want to make a release soon (latest on this weekend), so if you have suggestions, please post them now, otherwise they'll have to make it into the next release. This concerns both libimxvpuapi and gstreamer-imx. Also, note that not everything is supported by all encoders. I'll check what you suggested (key frames, RC buffer size etc.) |
Small update: I did not find yet controls for the IDR QP ratio. Neither did I see a generic RC buffer control. But I did find VBV buffer size controls. Would these be useful for you? |
Yes, VBV buffer size control is what people usually needs. Attached are my simple test apps to test dynamic bitrate and key frame on demand. Hope this key frame on demand will be useful for you. I see that key frame forcing is actually implemented on gstreamer-imx side (https://github.com/Freescale/gstreamer-imx/blob/master/src/vpu/encoder_base.c#L700) but for some reason it does not work. Dynamic bitrate change + VBV control + key frame on demand is gentleman's set of futures to make that encoder working good in live environment. I believe anyone who is doing something more complex that 'hello world live streaming' will appetite that. |
Actually I did not test key frame forcing after switching to OMX_Video_ControlRateVariable. In this strange world I won't be surprised that it will affect key frames. Will do that later today. |
Unfortunately, the VBV buffer size control in the Hantro driver goes nowhere. There is a CPB buffer size control, but it is commented out, with the extra comment: Enabling this seems to help, but I can't be sure that it doesn't cause adverse effects. Also, it requires patching the imx-vpu-hantro package. However, I was able to add code for forcing I/IDR frames via this flag: https://gstreamer.freedesktop.org/documentation/video/gstvideoutils.html?gi-language=c#GST_VIDEO_CODEC_FRAME_SET_FORCE_KEYFRAME |
Thank you for the key frames! Can you please point me to this CBP buffer size control, if this is open source? I wrote a few rate controls in the past so perhaps I'll find a way to use it (and will submit PR for your review at the end). |
It is contained in the imx-vpu-hantro package that is downloaded by the meta-freescale recipe of the same name. Inside, there's the file Note however that I had to turn off HRD to enable dynamic bitrate adjustments, so I am not sure if this field would help. The imx-vpu-hantro code is a mix of an OpenMAX IL interface with vendor extras & some internal code that is below that interface, so this can be quite confusing. |
There is in fact different way to make dynamic bitrate adjustments working - I can create GstBin, put there two IMX encoders (one 'current' and second 'next to be used') and switch between them in run time. This 'next to be used' can be stopped/configured/started where needed. That GstBin can expose all required encoder controls and act just like an encoder element with some tricky internals. And in this case enabling HRD would be actually good option. But I like your current approach and will stick with it. If I manage to get any rate control improvement then I'll submit them here. |
That could work, but would require switching at GOP granularities, since otherwise, references to previous frames would cause problems I guess. As for additions, I think I'll have to postpone those to the next libimxvpuapi and gstreamer-imx release, since I need to make one very soon. That way, there's more time later for a thorough analysis. |
As far as I see imxvpuenc_h264 is unable to change bitrate after switching to playing state. According to the source code it should work but instead of that in response to
g_object_set(G_OBJECT(videnc), "bitrate", 2000, nullptr);
I get the following:It is imx8mm + Linux 4.14.98 + gstreamer-imx v2.
Code is pretty straightforward - works on desktop with x264enc.
I believe I can't trace it deeper so I'd ask for help with that.
The text was updated successfully, but these errors were encountered: