Impact of stream quality for live coders



Jim Mc̮̑̑̑͒G
  ·  
27 May 2020  
  ·  
 14 min read

In this article, we explore stream settings, such as bitrate, that may work better to Twitch livecoders than the usual recommendations.

  • This article is an attempt to provide guidance with the choice of appropriate bitrate, informed by the outcome of a series of tests.

  • The take-away message for this article, is that we shouldn’t need to resort to using lower resolutions, we should be able to maintain a perfectly reasonable quality of stream, even at 1080p, just by turning the bitrate right-down, so as to fit within the limitations of even relatively poor ISP connections.

Tip: For those in a rush, you can find the test results towards the end of the article!

Introduction

I’ve been watching a lot of live coders on Twitch recently.

The question of “what is an appropriate bitrate for streaming for live-coders?” has caught my attention.

In part, the answer to this will of course be dictated by how much reliable bandwidth we have available in our own upload connection.

However, for other streamers this is not a limitation. Regardless, the selection of an appropriate bitrate is still something to think carefully about.

At time of writing, Twitch has an ingestion limit of 6000 Kbit/sec. However, even if you can technically upload your stream at this rate, unless you are a Twitch Partner, this choice is probably a really bad idea from the point of view of audience inclusivity.

For a vast majority of streamers, the data rate that you upload at, is the same rate that your audience will be consuming your stream with.

Not everyone in your audience will be able to reliably download at higher bitrates. Forcing an unnecessarily high bitrate will simply exclude people and/or drive viewers away:

  • people using mobile devices away from WiFi, perhaps on their train commute.
  • viewers in communities that simply do not have affordable ISP options available to them.

Note: Twitch does provide a transcoding service, which lets stream consumers select lower-quality versions of a stream to suit their connection. However, only Twitch Partners have guaranteed access to this. Check the table in the Twitch : Benefits FAQ for reference.



Live Coding at 720p or lower

I’ve noticed that quite a large number of people broadcast their live-coding stream at 720p. There are also a fair few who broadcast at 480p.

These folks usually downscale from a higher desktop resolution (typically 1080p).

Unless the presenter increases their font size from the typical IDE defaults, it can sometimes be a struggle to read the code - because it’s poorly defined and fuzzy.

I’ve asked a couple of presenters why they broadcast at lower resolutions - their typical answers have been:

  • they have limited or unreliable upload bandwidth from their ISP.
  • a commendable desire to better accommodate the bandwidth limits of their viewers.

When I’ve looked at the technical stats of their streams, a pattern that I see, is that they are quite often using much higher bitrates than they really need.

Example: I just watched one chap broadcasting his live-coding stream at 480p, whilst using a bitrate of 2Mbit/sec. If that amount of bandwidth is available to him, the choice to stream at such a low resolution seems an unusual decision.

Note: Many channel hosts are engrossed in their work and may not be aware that their audience can’t follow along so well. It probably doesn’t help if they’re working at a higher resolution on their own desktop and may forget that they need to increase the text size for their viewers.



What’s the usual advice for streamers?

I’ve been researching many different tutorials and guides about streaming. These are mostly YouTube videos delivered by millenials with an impressive skillset in AV presentation.

Note: … and an enviable amount of highly-styled head hair. It makes me jealous.

The main recommendation from these guys and girls is invariably: stream stability and framerate is king. Their advice is usually a variation of:

  • we should speedtest our bandwidth and upload our stream at just under that result, for stability (i.e. throw the highest bitrate we can at the stream)
  • if we don’t have great upload bandwidth, we should respond by reducing resolution.
  • avoid reducing stream bitrate, because “nobody wants to watch a bad-looking stream”.

Similarly, risking a poor-quality stream, with stuttering or dropped frames caused by a lack of computing performance, or inadequate upload-bandwidth, is to be avoided at all costs.


However, almost all of these folks are playing video games. Furthermore, many of the games are “twitch-reflex first-person-shooters” running at 60fps - I’m looking at you Fortnite players!

  • Games and video are almost always full-frame with fast-moving images.
    • This type of video requires higher bandwidth to maintain good visual fidelity.
    • Dropping resolution may not be all that noticeable - with games, we’re looking at big images, not pages of small text.
    • Dropped frames or poor video quality is more likely to drive viewers elsewhere.

screenshot obs settings



Live-coders produce a very different type of video

There are significant technical differences between the videos produced by live-coders and gamers (or other full-screen, fast moving content like a TV show or movie), that means that the usual rules of streaming may not necessarily apply to this subset of streamer!

  • Live coding is commonly about showing largely static content.
    • This type of video does not require as much bandwidth to maintain good visual fidelity.
    • Movement is typically confined to small areas (e.g. a thumbnail-sized talking-head), infrequent screen changes (e.g. displaying a different coding window).
    • The odd stutter, glitch or dropped frame isn’t really too much of a problem.
    • It’s less likely to be a deal-breaker for viewers, if a blurry window of code takes a half second to resolve into something that is clear to read.



What am I suggesting instead? (Conclusion)

I’ve been doing some testing with stream quality, experimenting with bitrates and compression quality.

We’ll talk about the testing process and look at the actual results, just a little later in this article.


In the meanwhile, as a live-coder who is:

  • conscientious about being bitrate-accessible to a wider audience
  • happy to leave some headroom in bandwidth - without necessarily aiming for the lowest bitrate possible
  • typically broadcasting a screen of largely static text with just a small talking-head in a corner

… then the following may be a good starting point:

  • 1080p
  • 60fps
  • Encoding set to max possible quality, preferably using CPU encoding if you can.
  • 1000-2000 Kbit/sec. 1500 Kbit/sec is likely to be a good starting point.

Unless you are really struggling with an ISP upload connection that is well under 1Mbit/sec, I’m not convinced that live coders should broadcast at 720p or lower for the purpose of reducing bandwidth.

The tests I performed seemed to indicate that, when using good encoding quality, we can get surprisingly usable 1080p results even at ~800Kbit/sec.

If our stream doesn’t look good, investigate the encoding quality carefully - the difference between fast encoding and quality encoding is pronounced.

Note: Let’s be absolutely clear that we are talking about the “live coders” subset of specifically, not streamers in general, where higher bitrates are most likely to be needed for acceptable results at 1080p



What about encoding quality?

  • Testing highlighted that the difference caused by compression quality becomes significantly more noticeable at lower bitrates.

  • Software (CPU x264) and hardware (NVidia GPU nvenc) encoding quality produced broadly similar results, although in some tests it seemed that CPU encoding was surprisingly better-looking.

    • As an example, I would specifically draw your attention to compare the results of CPU and GPU best-quality encoding at 800Mbps.
  • The choice of using CPU or GPU encoding is most likely to be one that is dictated by the hardware available.

    • If you have a beefy CPU with lots of cores (e.g. 8+cores) and good cooling, CPU encoding is probably the way to go, on the basis that the visual quality seems to have the edge.
    • If you have a laptop with a relatively constrained CPU (in terms of outright computing resource and thermal management), then using a GPU is likely to be the better choice.

Note: I didn’t test with Intel Quick Sync (using the built-in GPU present in Intel Core CPUs), but if there is enough interest I can add to the results another time.

screenshot obs settings



What about framerate?

An interesting observation from my testing is that broadcasting at 60fps is still surprisingly achievable - even with low bandwidth settings.

From a technical perspective, dropping from 60fps to 30fps means that we literally only need to send the data for half as many frames.

So, dropping to 30fps should be an obvious choice to improve visual quality … right?

… well, yes and no; This topic is a bit subjective and depends on preferences of the viewer.

Without a doubt, dropping to 30fps improved the frame-to-frame quality; In other words, if you were to take a screenshot from a 30fps video, that single frame would look better compared to the equivalent frame captured from a 60fps video. We would see fewer compression artifacts and “smudging effects”.

However, video is not about static screenshots, it’s about motion perception. An object in a moving video with a higher frame rate may be easier for our eyes to resolve, than one in a lower frame-rate video. A higher frame rate can lead to a higher perceived sharpness.

There is also a difference in the perception of immediacy/reality:

  • Using 60fps may help make your stream feel more life-like to your viewers. This helps to promote a sense of “being there with the person”.
  • Conversely, 30fps does make video look sharper, but it also may look a bit more like pre-recorded material and can feel “less immediate”.

We need to bring ourselves back to the fact that this article is about “streaming for live-coders”, not gamers. Live-coders don’t usually have full-screen moving images … we change something on-screen momentarily (e.g. open, or move a window) … and then the video stays largely static.

This means that if we use 60fps, we may experience a brief moment of degraded visual quality, but the video will rapidly restabilize back to relative sharpness. We’re then left with a talking-head at 60fps which may be more desirable.



Let’s talk about video encoding

Before we look at the testing results, it probably helps to have at least a fundamental understanding of video compression.

Uncompressed video is prohibitively vast in size, so even from the very early days of digitised video, the industry has always worked with encoding systems that reduce file size and memory usage.

Over time, the algorithmic efficiency of these encoding systems has improved meaning that we can create smaller video files that retain good visual fidelity.

This isn’t entirely a software issue, as we have needed increasingly more powerful en/decoding compute in order to work with these increasingly data-dense encoding formats in real-time.

Note: This means that streaming to platforms such as Twitch is all about being able to encode bluray-quality video in real-time. Which is utterly amazing if you stop to think about it for a moment.

There are hundreds of video codecs, but common ones that you are most likely to hear about include:


The basic gist of video compression is as follows:

  • we periodically send a “key-frame” - this is a complete image. Think of this as being a jpeg image of the entire frame, typically sent every other second.
  • we then send a series of “frame deltas” of the video - i.e. just the bits of the picture that have changed from the previous frame. This is a mathematically encoded “estimation” of the movement.
    • For example, if we have a video which has mostly unmoving content, but perhaps just a person talking - we send just the changes that are appearing to that person’s face.
  • just as with a static jpeg image, we can create video files that have different quality settings; - small files will lose visual fidelity, big files can look better. Reducing quality in a compressed video usually manifests with it becoming more blurry or having strange visual artifacts such as “smearing effects”.
    • we may not always be able to use higher-quality encoding because it is increasingly more CPU intensive … our computing resources may not have enough power to keep up with the rate of the video.
  • the amount of movement in the video has an impact on the data required to generate the frame-to-frame delta of the video.
    • if we have lots of fast-moving, full-frame motion, we need more data.
      • e.g. live-action sports, where the camera is panning to tracking a player.
    • largely static scenes require less data.
      • e.g. a camera filming a locked-shot, with a relatively distant person walking across the scene.
  • compressed video can be:
    • fixed bitrate, where the quality of the compression is adjusted to fit a constant amount of bandwidth.
      • lots of fast full-frame changes causes quality to drop
      • predominantly unchanging video can use available bandwidth to improve the overall visual fidelity across the screen.
    • variable bitrate, where the relative quality of the video is the same, but the bandwidth fluctuates as the video changes.
    • streaming platforms like Twitch work with fixed bitrates. They may, optionally, provide multiple separate streams of the same content, offering different quality/bandwidth choices for different customers.
  • You can read more at Wikipedia : Video compression picture types



Show me the test results

I wanted to better understand what the impact of changing just two key settings would be upon a stream:

  • bitrate
  • compression quality.

For my testing, videos were created at 1080p at 60fps.


The testing process is:

  • I recreated an otherwise empty desktop, with a single window containing code in it.
  • The window was programmed to pan from side-to-side in a consistent and repeatable way.
  • I used OBS Studio to record streams


The test videos include :

  • a static window
  • a slowly-panning window
  • a rapidly-panning window

Note: I have hosted the original .mp4 files myself, with the intention that this will avoid us seeing any re-compression artifacts. If these videos were uploaded to a video-hosting service like YouTube, we would have no control over the quality the video you actually see.


Notes about the results

I’ll leave it to you to look at the test results and draw your own conclusions, but here are some thoughts:

  • Use the highest encoding quality that your computer will tolerate. It can breathe life even into low bitrate streams.
  • 200 Kbit/s has been included, not because we should ever consider using it, but it is useful to know what bad-quality really looks like, and to better visualise how compression is working.
  • 500 Kbit/s is a bitrate that I found really interesting to explore. It’s still too low to really recommend as being be usable, but it makes visualising the influence of other factors much easier:
    • it’s interesting to see the improvement that just 300Kbit/s makes.
    • software-encoded at maximum quality is actually amazingly good.
    • compare, in particular, the difference between software-encoded-maxquality and hardware-concoded-maxquality; at this bitrate the difference is extremely noticeable.
  • 3000 Kbit/s has been included as an example of great quality, but could arguably be an unnecessarily high bitrate for live-coding!
  • 800 Kbit using maximum quality should come as a surprise to many, as it “feels like it should be too low” but yielded a tolerable result.
  • 1500 to 2000 Kbit could possibly be a sweet-spot for livecoders!
    • Compare the test videos below and see if you agree!
  • Although the movement of the window has been scripted, the stop/start of the video was done manually by me … so the video length and filesize will be a bit inconsistent.




Tip: You should hit the maximize button for a better look.

200 Kbps, 60fps

200kbps : hardware : lowlatencyperformance:


200kbps : hardware : maxquality:


200kbps : software : slower:


200kbps : software : veryfast:



500 Kbps, 60fps

500kbps : hardware : lowlatencyperformance:


500kbps : hardware : maxquality:


500kbps : software : slower:


500kbps : software : veryfast:



800 Kbps, 60fps

800kbps : hardware : lowlatencyperformance:


800kbps : hardware : maxquality:


800kbps : software : slower:


800kbps : software : veryfast:



1500 Kbps, 60fps

1500kbps : hardware : lowlatencyperformance:


1500kbps : hardware : maxquality:


1500kbps : software : slower:


1500kbps : software : veryfast:


3000 Kbps, 60fps

3000kbps : hardware : lowlatencyperformance:


3000kbps : hardware : maxquality:


3000kbps : software : slower:


3000kbps : software : veryfast:



Further reading

If you find my content helpful, please consider sharing the love with a GitHub Sponsorship - equivalent to a cup of coffee every other week.





Archives

2020 (23)
2019 (27)