Kurento video recordings have very low bitrate, seems to be hard capped at 300Kbps - recording

We have a WebRTC application that records video server side using Kurento Media Server. The stream runs through Kurento and it is simultaneously recorded to WEBM VP9.
The quality of the video during the call is 1280x720 as expected. The quality of the recording is usually lower than 640x480 - the resolution seems to change during the recording, but is maintains constant bitrate around 300Kbps.
The resulting recording is extremely low quality.
We tried to affect the bitrates by changing the bitrates on RecorderEndpoint
recorder.setMaxOutputBitrate(0);
recorder.setMinOutputBitrate(1000000);
We also tried to set bitrates on WebRTCEndpoint
webRtcEndpoint.setMaxVideoRecvBandwidth(0);
webRtcEndpoint.setMaxVideoSendBandwidth(0);
webRtcEndpoint.setMinVideoRecvBandwidth(750);
webRtcEndpoint.setMinVideoSendBandwidth(750);
webRtcEndpoint.setMaxOutputBitrate(0);
webRtcEndpoint.setMinOutputBitrate(1000000);
Setters are called before the recording starts.
This should set the video bitrate for recording to 1Mbps, but it does not have any effect. It seems to be a common problem, but there seem to be no solution other than setting the minimum output bitrate which does not work for us.
How can we increase the bitrate of the recording?

Related

WebRTC Stream Freezes When Picture Complexity Increases

I am developing an application that uses WebRTC to display a live video stream being captured from a V4L2 source. The stream originates from a Linux box that has a DVI-USB capture card, is encoded to H264 by ffmpeg and sent to RTP, received by a Janus WebRTC server which is accessed by the web interface.
Here is my current ffmpeg command - pretty simple:
ffmpeg -f v4l2 -i /dev/video0 -vf "transpose=1,scale=768:1024" -vcodec libx264 -profile:v baseline -pix_fmt yuv420p -f rtp rtp://10.116.80.86:8004
I can't go into details, but the DVI source generates a portrait 768x1024 image that initially is a simple image where the only movement is a small clock near the center that increments every second. At this stage, everything appears to work great. The image is high-quality and continuous/smooth in the browser.
Once I interact with the DVI source, a more complex image is generated, with some text/lines in the upper half. Still not very complex - only 2 colors involved and some basic 1px line shapes, and only the little clock is moving. At this point, the video starts to freeze frequently, and only updates once in a while for a few seconds. Bandwidth should not be an issue here, and the bitrate appears to stay high. However, many fewer frames are decoded.
I have also tried scaling the video down to 480x640 from 768x1024 and with that change the issue does not occur. However, I really need the full resolution and, again, there should not be a bandwidth issue here.
I have also tried capturing the output of ffmpeg to a file rather than streaming to RTP and in the file everything is good.
Here is a screenshot of the WebRTC internals (in Edge) for this stream. You can clearly see when the video image changes from the simple clock to including more shapes & text (nothing is changed here other than the image from the DVI source):
In Firefox, the video just freezes whenever frames are not decoded. In Edge, the video goes black after a moment with no frames decoded.
Any ideas as to what might be causing this?
Answering my own question for future Googlers:
I ended up figuring out that this was due to the WebRTC server (Janus) running on a Raspberry Pi. Apparently the Pi 3B+ was powerful enough to handle the packet flow when the bitrate was low (just the clock), but when the rate got higher it would choke.
I re-hosted Janus on a more powerful server and all is working well.

Implementing custom h264 quantization for Ffmpeg?

I have a Raspberry Pi, and I'm livestreaming using FFmpeg. Unfortunately my wifi signal varies over the course of my stream. I'm currently using raspivid to send h264 encoded video to the stream. I have set a constant resolution and FPS, but have not set bitrate nor quantization, so they are variable.
However, the issue is that the quantization doesn't vary enough for my needs. If my wifi signal drops, my ffmpeg streaming speed will dip below 1.0x to 0.95xish for minutes, but my bitrate drops so slowly that ffmpeg can never make it back to 1.0x. As a result my stream will run into problems and start buffering.
I would like the following to happen:
If Ffmpeg (my stream command)'s reported speed goes below 1.0x (slower than realtime streaming), then increase quantization compression (lower bitrate) exponentially until Ffmpeg speed stabilizes at 1.0x. Prioritize stabilizing at 1.0x as quickly as possible.
My understanding is that the quantization logic Ffmpeg is using should be in the h264 encoder, but I can't find any mention of quantization at all in this github: https://github.com/cisco/openh264
My knowledge of h264 is almost zilch, so I'm trying to figure out
A) How does h264 currently vary the quantization during my stream, if at all?
B) Where is that code?
C) How hard is it for me to implement what I'm describing?
Thanks in advance!!

Why is live video stream not fluent while audio stream is normal when they are played by Flash RTMP Player after being encoded

My video stream is encoded with H.264, and audio stream is encoded with AAC. In fact, I get these streams by reading a file whose format is flv. I only decode video stream in order to get all video frames, then I do something by using ffmpeg before encoding them, such as change some pixels. At last I will push the video and audio stream to Crtmpserver. When I pull the live stream from this server, I find the video is not fluent but audio is normal. But when I change gop_size from 12 to 3, everything is OK. What reasons cause that problem, can anyone explain something to me?
Either the CPU, or the bandwidth is not sufficient for your usage. RTMP will always process audio before video. If ffmpeg, or the network is not able to keep up with the live stream, Video frames will be dropped. Because audio is so much smaller, and cheaper to encode, a very slow CPU or congested network will usually have no problems keeping up.

Timing Issues When Muxing Audio and Video with libav

I have series of encoded packets, H.264 video and AAC audio. As they're coming on, I'm writing them to a video file, using av_write_frame.
Given the following situation in a row
10 seconds of video, then
10 seconds of video and audio, then
10 seconds of video.
Everything muxes fine and when played back via VLC or QuickTime, everything looks good. If I play it in Windows Media Player, the audio is played immediately.
It seems I'm doing something wrong, but checking the PTS of the audio stream packets, they are set to 10 seconds based on the time base of the audio stream.
It seems that it's best to inject empty audio packets at the beginning of the stream. This is the only way that video playback in WMP would work. Every player handles the streams differently and this is the best way to ensure compatibility across players.

What movie formats and resolutions should be generated to ensure cross-browser/platform compatibility?

I'm looking to generate web videos from movies taken with my digital camera. What formats should I generate, and at what resolution and bitrate to ensure playback on mobile and desktop devices?
Here's what I was thinking:
Input format: AVI, MOV
Output format: webm, ogv, mp4
Output resolutions: 1080p, 720p, 320p
Not really a programming question but I will answer it anyways:
WebM can be ditched completely. Very few devices support it. mp4 is the most common format that all devices support. Low end phones support 3gpp format instead [cousin of mp4]. If you have it you should be fine for 90% of the devices.
mp4 with h.264/aac is the most common and for devices that don't support those mpeg4 with mp3 will suffice.
How many devices do you have are 1080p resolution. Better to ditch the 1080p and get one SD resolution 480p in there.
Bitrates depend on the encoding profile and content. Just ensure do two pass encoding using ffmpeg and libx264 to get the best quality.
Most mobile devices can display "HD" content fairly well, these days. However, if you're looking to save on bandwidth on peoples data plans, a good resolution would probably be 852x480.
now, depending on if you need near lossless quality, or if you can accept minor artifacts in your video will determine your bitrate. for 1080p and x264, you can get near lossless with about 15mbps, but you could have watchable video with 10-11mbps. im not sure how well the other codecs compare, so you may have to try a couple test runs with a short video.
if you do 720p, you can most certainly get away with 4-6mbps.
with 852x480, you may be successful with as low as 1.5-2mbps.
480x320, or maybe even 320x240 may be a good option, if you suspect people will be watching this on lower end devices or on really slow connection, or very limited bandwidth. you could probably get away with 500kbps for 320x240, and 1mbps for 480x320.
these are all starting points, as each codec and selected encoding options will increase/decrease the quality. but i believe these to be good starting points.

Resources