The Programs of the Week of a Big Work Milestone
This Week’s Program: June 19 - June 23
The big story this week is the completion of a huge project for my team at work. This week, we quietly released a big new thing into the world. I’ll talk about it more next week, but this is something we’ve been working on for about a year. I’m super proud to be a part of it and can’t wait to share more of the details next week.
Last week, my work in Overscan was frustrating. This week I identified two real causes of that frustration.
d7eced4a32951e9a0f88c2cea5840b4284760865
To start, I tear down most of the pieces of my pipeline and just run
some tests between vtenc_h264
and x264enc
. No matter how I tuned
Apple’s vtenc_h64
encoder, I always got a black screen when
broadcasting. Back to the CPU-hungry x264enc
.
Encoding is frustrating.
After a bit more experimentation I find that setting the tune
property to zerolatency
does something meaningful. I still don’t
know what exactly it means, but I was seeing the stream crash whenever
I switched from one input to the other, and with this property set I
wasn’t seeing that. I read it has something to do with
latency. Imagine that. I still don’t know for certain.
More commits here, all around simplifying the pipeline to have the least pieces necessary to get a stream up and running.
4471d40610faa2d434f7c23baaf3455a9976506c
Normalizing video sources is frustrating.
Let’s say you have a video source with a 4:3 aspect ratio that you
need to fill a 16:9 frame. When you ask GStreamer to do this,
GStreamer will awkwardly stretch the source to fill the frame. To stop
this from happening, you need to drop in a videoscale
element. In
the Caps
(remember that’s GStreamer’s shorthand for “capabilities”)
before and after the videoscale element, you need to make sure there’s
a pixel-aspect-ratio=1/1
setting. This makes the video appropriately
apply black bars around the video source. If you’re using a Mac’s
iSight camera, what happens now is that the normally crisp video
source now looks like real bad uprezzed crap.
That’s because the camera on a Mac has a set of presets and can only
conform to certain resolutions. Without an explicit Cap saying “hey
camera I want you to be at this resolution”, the avfvideosrc
will
give us a small resolution and scale it up.
Here’s my conundrum. I want Overscan to be able to accept any kind of
videosrc in a scene. When you call (camera 0)
, Overscan should
create an element representing the camera, and putting that in a scene
should just work. But I also want Overscan to produce good looking
video. I’m torn about how to make my API generic and do the right
thing vis-à-vis normalizing and scaling video sources to produce the
optimal image.
4195d0b1f4364be90be199d3dabb73f37e12dcfe
Similar to scaling, one problem I encountered when trying to stream my
screen was I found that I wasn’t setting an appropriate
framerate. When I explicitly set an fps of 30 frames per second in my
Caps, my screen capture appears just fine, but the camera connected to
my display can’t deal with that! It needs a videorate
element thrown
in the mix. But the camera on my MacBook Air seems to be fine without
a videorate
.
How to normalize these things without compromising quality and increasing complexity in the API. This is the question!
I think at this point I could attempt another live stream without major incident, but I want to spend another week really tuning stream quality and getting this API in a good spot to handle a diversity of video sources without choking.
Until then,
Mark