Close
0%
0%

Streamo Encodo Cheapo

Trying to make an inexpensive HDMI encoder with off the shelf stuff

Public Chat
Similar projects worth following
0 followers
There are many commercially available HDMI encoder boxes available. They take HDMI video inputs and output it as a TCP/IP network stream. Available devices have from one to several HDMI inputs to output as independent network streams.

These devices have a retail cost of US$75-100 per HDMI input channel. I'm trying to see if I can use cheap HDMI-to-USB capture dongles to implement something similar with adequate features and performance at a much lower cost.

This is mostly an integration project, exploiting the existing work of many other hands and brains.

The itch

Oh, yes, I am drawn to the siren song of being a cord cutter. I pay too much for TV content. It's not that I can't afford it ... it's just that I don't think it's worth the money I'm being charged. I'm happy with the couple of streaming services we subscribe to, but the broadcast linear TV service is too expensive. We get something like 7 million channels, but we probably only regularly watch under a dozen. Some of those dozen are local broadcast channels.

We get mostly great over-the-air (OTA) reception of local broadcast channels with my roof-mounted antenna. However, there is one local channel that I want but cannot get that way. We live northeast of Seattle. We are lucky in this area because there are two PBS stations: KCTS in Seattle and KBTC in Tacoma. We are paid members of both. As expected, there is a huge overlap in their programming, but each carries some things not carried by the other. (My understanding is that this is by design.) I've tried many RF-related things, but I just cannot get any of my digital TV tuners to recognize KBTC. KBTC also has a secondary transmitter in downtown Seattle, but I guess the signal is just not strong enough to reach me and be above the noise threshold that the tuners want.

So, my quest is for ways to receive KBTC programming without paying some streaming service's "with local channels" prices, which are pretty steep IMHO. We can already watch (much) KBTC programming on demand via PBS Passport, and we can watch the live feed via apps or a web browser. The other factor for us is wanting to be able to record things to our local DVR. The app and web browser pathways don't directly provide that.

  • UVC and UAC

    WJCarpenter05/27/2024 at 19:28 0 comments

    I don't know whether to file this under "learn something new every day" or "teach an old dog new tricks", but I recently looked into a standard called USB video device class (UVC) published by the USB Implementers Forum. (There is a companion standard, UAC, for audio, but I haven't looked at that.) The dongles based on the MS2109 and MS2130 chips advertise UVC and UAC compatibility, but I didn't really know what that meant beyond "don't need to install custom drivers". The dongles also expose a USB HID device, and I had assumed that any configuration control of them would be via the USB HID. Not so.

    UVC is one of those standards where any particular device is likely to only implement some subset, and that is true of these dongles. UVC provides protocol elements for querying or changing lots of different configuration items. There are multiple open source utilities that can be used to interact with UVC devices. For example, yavta and v4l-utils. Here are some examples for my MS2130 dongle:

    This reports the available video modes, resolutions, and frame rates (figures for frame rates are quoted as frame intervals, so 1/60 is 60fps):

    $ sudo yavta --enum-formats /dev/video2
    Device /dev/video2 opened.
    Device `USB3 Video: USB3 Video' on `usb-0000:00:15.0-1' (driver 'uvcvideo') supports video, capture, without mplanes.
    - Available formats:
        Format 0: YUYV (56595559)
        Type: Video capture (1)
        Name: YUYV 4:2:2
        Frame size: 1920x1080 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1600x1200 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1360x768 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1280x1024 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1280x960 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1280x720 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1024x768 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 800x600 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 720x576 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 720x480 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 640x480 (1/60, 1/50, 1/30, 1/20, 1/10)
    
        Format 1: MJPEG (47504a4d)
        Type: Video capture (1)
        Name: Motion-JPEG
        Frame size: 1920x1080 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1600x1200 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1360x768 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1280x1024 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1280x960 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1280x720 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 1024x768 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 800x600 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 720x576 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 720x480 (1/60, 1/50, 1/30, 1/20, 1/10)
        Frame size: 640x480 (1/60, 1/50, 1/30, 1/20, 1/10)
    
    Video format: YUYV (56595559) 1920x1080 (stride 3840) field none buffer size 4147200$ sudo v4l2-ctl -d2 --set-fmt-video "pixelformat=MJPG
    

     This switches the video mode from YUYV to MJPG

    $ sudo v4l2-ctl -d2 --get-fmt-video
    Format Video Capture:
        Width/Height      : 1920/1080
        Pixel Format      : 'YUYV' (YUYV 4:2:2)
        Field             : None
        Bytes per Line    : 3840
        Size Image        : 4147200
        Colorspace        : sRGB
        Transfer Function : Rec. 709
        YCbCr/HSV Encoding: ITU-R 601
        Quantization      : Default (maps to Limited Range)
        Flags             : 
    
    $ sudo v4l2-ctl -d2 --set-fmt-video "pixelformat=MJPG"
    
    $ sudo v4l2-ctl -d2 --get-fmt-video
    Format Video Capture:
        Width/Height      : 1920/1080
        Pixel Format      : 'MJPG' (Motion-JPEG)
        Field             : None
        Bytes per Line    : 0
        Size Image        : 4147200
        Colorspace        : sRGB
        Transfer Function : Rec. 709
        YCbCr/HSV Encoding: ITU-R 601
        Quantization      : Default (maps to Full Range)
        Flags             : 
    

    These tools tend to think you already know what the various parameters mean, but they are quite handy once you get the hang of them. The settings seem to stick, at least for the specific dongle that I have. If I unplug it and replug it, it remembers what I last set. The bad news is that the video playing software that I have handy (vlc and ffplay) seem to want to tweak some of the UVC settings, probably to better suit how they handle...

    Read more »

  • syslog for MS2130 dongle

    WJCarpenter05/24/2024 at 00:20 0 comments

    When plugging the MS2130-based HDMI capture dongle, /var/log/syslog says this:

    2024-05-23T17:05:32.366859-07:00 yogi kernel: [14895.900908] usb 2-1: new SuperSpeed USB device number 5 using xhci_hcd
    2024-05-23T17:05:32.398878-07:00 yogi kernel: [14895.933905] usb 2-1: LPM exit latency is zeroed, disabling LPM.
    2024-05-23T17:05:32.422841-07:00 yogi kernel: [14895.956505] usb 2-1: New USB device found, idVendor=345f, idProduct=2130, bcdDevice=31.00
    2024-05-23T17:05:32.422889-07:00 yogi kernel: [14895.956531] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    2024-05-23T17:05:32.422895-07:00 yogi kernel: [14895.956540] usb 2-1: Product: USB3 Video
    2024-05-23T17:05:32.422899-07:00 yogi kernel: [14895.956546] usb 2-1: Manufacturer: UltraSemi
    2024-05-23T17:05:32.422902-07:00 yogi kernel: [14895.956552] usb 2-1: SerialNumber: 20210623
    2024-05-23T17:05:32.438897-07:00 yogi kernel: [14895.973543] usb 2-1: Found UVC 1.00 device USB3 Video (345f:2130)
    2024-05-23T17:05:32.498521-07:00 yogi kernel: [14896.032696] hid-generic 0003:345F:2130.000A: hiddev0,hidraw1: USB HID v1.10 Device [UltraSemi USB3 Video] on usb-0000:00:15.0-1/input4
    2024-05-23T17:05:32.503063-07:00 yogi mtp-probe: checking bus 2, device 5: "/sys/devices/pci0000:00/0000:00:15.0/usb2/2-1"
    2024-05-23T17:05:32.503640-07:00 yogi mtp-probe: bus: 2, device: 5 was not an MTP device
    2024-05-23T17:05:32.592287-07:00 yogi (udev-worker)[16747]: controlC1: Process '/usr/sbin/alsactl -E HOME=/run/alsa -E XDG_RUNTIME_DIR=/run/alsa/runtime restore 1' failed with exit code 99.
    2024-05-23T17:05:32.603188-07:00 yogi systemd[4030]: Reached target sound.target - Sound Card.
    2024-05-23T17:05:32.606696-07:00 yogi mtp-probe: checking bus 2, device 5: "/sys/devices/pci0000:00/0000:00:15.0/usb2/2-1"
    2024-05-23T17:05:32.606803-07:00 yogi mtp-probe: bus: 2, device: 5 was not an MTP device
    2024-05-23T17:05:32.715245-07:00 yogi wireplumber[4049]:  Failed to call Lookup: GDBus.Error:org.freedesktop.portal.Error.NotFound: No entry for camera
    

    A relevant detail is that it has both the video and audio device stuff, but it also has a HID interface. There is some reverse engineered work for doing things via that HID interface here: https://github.com/BertoldVdb/ms-tools

    In contrast, when plugging the device into a USB 2.0 port, it's logged as:

    2024-05-24T10:47:05.913518-07:00 yogi kernel: [42791.625745] usb 1-4.2: new high-speed USB device number 13 using xhci_hcd
    2024-05-24T10:47:06.093496-07:00 yogi kernel: [42791.807407] usb 1-4.2: New USB device found, idVendor=345f, idProduct=2130, bcdDevice=21.00
    2024-05-24T10:47:06.093516-07:00 yogi kernel: [42791.807417] usb 1-4.2: New USB device strings: Mfr=1, Product=5, SerialNumber=7
    2024-05-24T10:47:06.093520-07:00 yogi kernel: [42791.807419] usb 1-4.2: Product: USB2 Video
    2024-05-24T10:47:06.093521-07:00 yogi kernel: [42791.807421] usb 1-4.2: Manufacturer: UltraSemi
    2024-05-24T10:47:06.093521-07:00 yogi kernel: [42791.807423] usb 1-4.2: SerialNumber: 20210621
    2024-05-24T10:47:06.113028-07:00 yogi kernel: [42791.826992] usb 1-4.2: Found UVC 1.00 device USB2 Video (345f:2130)
    2024-05-24T10:47:06.183876-07:00 yogi kernel: [42791.897291] hid-generic 0003:345F:2130.0013: hiddev0,hidraw6: USB HID v1.10 Device [UltraSemi USB2 Video] on usb-0000:00:15.0-4.2/input4
    2024-05-24T10:47:06.187848-07:00 yogi mtp-probe: checking bus 1, device 13: "/sys/devices/pci0000:00/0000:00:15.0/usb1/1-4/1-4.2"
    2024-05-24T10:47:06.188320-07:00 yogi mtp-probe: bus: 1, device: 13 was not an MTP device
    2024-05-24T10:47:06.286059-07:00 yogi (udev-worker)[77117]: controlC1: Process '/usr/sbin/alsactl -E HOME=/run/alsa -E XDG_RUNTIME_DIR=/run/alsa/runtime restore 1' failed with exit code 99.
    2024-05-24T10:47:06.315144-07:00 yogi mtp-probe: checking bus 1, device 13: "/sys/devices/pci0000:00/0000:00:15.0/usb1/1-4/1-4.2"
    2024-05-24T10:47:06.315285-07:00 yogi mtp-probe: bus: 1, device: 13 was not an MTP device
    

    To round things out, here's how the MS2109 dongle is logged (it only...

    Read more »

  • The five hurts

    WJCarpenter05/22/2024 at 01:39 0 comments

    I figured out what's up with the 5fps over the cheap dongle I have. In fact, I ordered a second, newer looking dongle, and it also gave me only 5fps.

    Essentially all of these low-cost HDMI-to-USB dongles are based on the Macro Silicon MS2109 chip. It took some sleuthing, but I eventually found a datasheet for that chip. The chip has two output modes: YUV422 and MJPEG. MJPEG is what we really want, and the chip can output up to 1920x1080@30fps. In YUV422 mode, it's limited to 1920x1080@5fps. The dongles (at least the ones that I have) are configured for YUV422 mode, and that can't be changed without modifying the firmware in EEPROM. I don't know why the manufacturers selected that very limited output format.

    Meanwhile, it looks like the go-to chip for the recent generation of those dongles is the Macro Silicon MS2130 (datasheet). In addition to the faster USB 3.0 interface, it supports output of 1920x1080@60fps for both YUV422 and MJPEG outputs. (The datasheet says the chip can be programmed to output 4K@15fps, but I haven't seen that mentioned in any advertisements for these things.

    The older MS2109 dongles can be had for around US$10, and the newer MS2130 dongles go for around US$20. For this sort of project, that price difference doesn't matter too much. I got a dongle with an MS2130 chip:

    Bus 002 Device 094: ID 345f:2130 UltraSemi USB3 Video

    It does, indeed, emit video at FHD@60fps. 

    I could wish that it emitted MJPEG, but at least I am seeing the full resolution and frame rate.

  • Expensive-ish HDMI encoder

    WJCarpenter05/18/2024 at 22:54 0 comments

    When I started thinking about this cheap encoder project, I assumed it was more likely than not that it wouldn't be good enough for household TV watching. To hedge my bets, I ordered a standalone HDMI encoder box. It's this one:

    I selected this one according to the Cheap and Lazy algorithm. I saw it mentioned by some other people, and it was inexpensive relative to others mentioned. It was also readily available with just a short delay. The day I bought it, there was also an instant coupon for US$20 off the price.

    I ran the same sort of POC test with this device that I ran with the cheap encoder dongle earlier. Results were pretty good. Here is what vlc says about the stream:

    vlc was able to consume and display a very clear image with both H.264 and H.265 codecs. Despite best efforts, I was only able to get a frame rate of 30fps. I'm not sure if that's a limitation of the device, a limitation of the Fire TV stick, or some other settings thing. The video and audio were completely smooth in vlc.


    As a side note, there was some small inconvenience as a side effect of buying the least expensive device. The setup instructions are for Windows (whatever that is), and the device comes configured with a static IP address of 192.168.1.120. I already have a device with that address, so I had to temporarily turn it off while I configured this new device. Luckily, there is a simple web UI that lets you change the network configuration and various other things. There was an unexpected bonus (because I didn't pay attention to it while shopping). The device can record to an SD card for subsequent download. I don't know if I'll ever use that, but it's nice to have.

    Regardless of what happens with this overall project, I should be able to scratch my single-channel itch with this device after applying some software magic.

  • Proof of concept

    WJCarpenter05/17/2024 at 22:28 0 comments

    Do those dongles actually work, and are they better than "marginally above crap"? Let's see what we can see.

    When I plug the dongle into my Linux machine, it shows up as this USB device:

    Bus 001 Device 038: ID 534d:2109 MacroSilicon

     Searching around for those ID strings leads to the MacroSilicon MS2109 chip that powers the dongle that I have. I haven't pursued the innards of this chip, but it was easy to figure out that it's supported by the Linux v4l subsystem and presents as a pair of video devices.

    crw-rw----+ 1 root video 81, 2 May 17 11:36 /dev/video2
    crw-rw----+ 1 root video 81, 3 May 17 11:36 /dev/video3
    

     At this point, I just needed any old HDMI video signal. I plugged in an Amazon Fire TV stick that was in my "send to the thrift store" box. I used vlc to open /dev/video2 as a capture device.

    Hey, that worked! You can't see it, but the audio also played correctly. On my 4k monitor, that window with the FHD video doesn't look completely sharp, but it's good enough for the POC. Here's what vlc says about it:

    The resolution is FHD (1920x1080), but it's only 5fps. The playing video has the choppy look that you'd expect from that frame rate. My quad-core low-powered Linux box reports about 30-50% on each core.

    It didn't really prove anything that I didn't already know was OK, but I also streamed that video. My first attempt was to use mjpg-streamer, which I had used in an earlier project., but some python thing was giving me a hard time today. Instead, I used µStreamer, which is part of the PiKVM project. It doesn't include audio for this kind of setup, but I was able to view the playing video in a web browser.

    Next steps: I've ordered a newer dongle that has a USB 3.0 interface, and I have some beefier Linux boxes to try. I am cautiously optimistic.

  • The HDMI dongles

    WJCarpenter05/17/2024 at 22:01 0 comments

    There are dongles that take HDMI input and plug into a USB port for output, and they are extremely cheap. They are readily available online for US$10-20. I've had one that looks like this for several years:

    Until today, I'd never plugged it in. It was probably pretty cheap and I bought it for hazy future use after seeing it mentioned in some article somewhere. The future is now! The documentation that came with it claims it can accept an input of 4K@30fps and output FHD@30fps. I don't know if that claim is actually true. Even if it is, 30fps is less than desirable for watching TV. Newer iterations of similar dongles claim to output up to FHD@60fps. My TV is only FHD, not 4K, so FHD@60fps would be fine for now if it turns out to be true.

  • The DVR

    WJCarpenter05/17/2024 at 21:52 0 comments

    DVR, I hear you ask. These days, it's relatively easy to create your own DIY DVR with inexpensive hardware. For example, a Raspberry Pi with a couple of USB hard drives is enough computer power. Digital tuners are available for receiving OTA programming. The most well-known is HDHomeRun, but there are others. Many paid programming services also make their live TV content available for streaming via a technology called TV Everywhere. For the software, I've experimented with Channels DVRemby, and a few others. None are perfect, but several are good enough.

    One of the side-effects of these various DIY DVR efforts is that the people involved, both the developers and the users, have lots of interesting ideas for how to deal with programming. It is some of those ideas that I am exploring in this project. In particular, it's aspects of these very long discussion threads in the Channels DVR community forums that set me to thinking.

    BETA: Chrome Capture for Channels

    HDMI for Channels

    ADBTuner: A “channel tuning” application for networked Google TV / Android TV devices

View all 7 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates