MythTV / mythtv

The official MythTV repository
https://www.mythtv.org
GNU General Public License v2.0
705 stars 346 forks source link

Allow usage of experimental DVB mmap API #454

Open KungFuJesus opened 2 years ago

KungFuJesus commented 2 years ago

Is your feature request related to a problem? Please describe. Not a problem.

Describe the solution you'd like While the existing read() based demux is working fine, the Linux kernel has offered an experimental feature to directly mmap the buffers into userspace, allowing to reduce context switches. This should, in theory, reduce potential latency and stutters when viewing liveTV and maybe even reduce the necessary ring buffer sizes for digital TV. See here: https://www.kernel.org/doc/html/v5.15/userspace-api/media/dvb/dmx-mmap.html

There are examples of this in v4lutils for v4l2 devices, but not so much for dvb support. I likely will take a swing at this myself, if someone can point me to the places the transport stream demuxing occurs that I'll need to modify. The other tricky bit is that I tend to operate on the fixes branch, so I may need to initially implement support on there and backport the changes into master.

I asked about the "experimental" status that's been associated with this API on the linux-media ML, and the reply I had received was that there was nothing seriously wrong with it, so I think it's worth pursuing.
https://lore.kernel.org/linux-media/20220108233326.364c1edf@coco.lan/T/#t

kmdewaal commented 2 years ago

Have a look at dvbstreamhandler.cpp function RunTS and at DeviceReadBuffer.cpp. This is a bit of documentation on the basic MythTV recording architecture: https://www.mythtv.org/wiki/IPTVRecorder Enjoy!

KungFuJesus commented 2 years ago

Have a look at dvbstreamhandler.cpp function RunTS and at DeviceReadBuffer.cpp. This is a bit of documentation on the basic MythTV recording architecture: https://www.mythtv.org/wiki/IPTVRecorder Enjoy!

The streamhandler portion of that document makes a great deal a sense. This must be how multiplexed digital streams record simultaneously, they are pulled out of the same demux'd buffer. From what I can tell this should be an easy feature but it's probably something we'd want to allow a toggle for (for one, you need support for it as a compiled module or compiled into your kernel). How hard is it to write a setting that gets stashed in the database for this?

KungFuJesus commented 2 years ago

Also it looks like some devices need DeviceReadBuffer while others don't. I take it one type of device is more common to wrap in this than another? Maybe the distinction is something external like an HDHomeRun versus a tuner card?

It's very tempting to bolt this on by bypassing reads and just doing direct memcpy's into the internal buffers but half of the benefit of this is copy elimination. Doing the above only eliminates the need to context switch for servicing the syscall, whereas if I modify things to present the mmap'd buffers and returns pointers into that directly, I save quite a few round trips through memory. Is there sufficient copying on the demux that this is relatively safe? A lot of the "did we receive enough data" logic seems to be the return of the read call. I suspect a lot of this complicated logic goes away by means of mmap.

There seems to be a polled interface used for getting device status. I suspect that there's an analogous way to do this with memory mapped buffers that doesn't involved opening a pipe and polling over it.