HMDI input issue: handshake not showing 4k support

I just set up a Rock 5b, which is an amazing board. I’m hoping to use it to capture video from a Sony A7s (mk 1), and it’s working great for 1080p capture with gstreamer.

The problem I’m encountering is that the A7s will only let me turn on 4k HDMI output when it’s connected to a device that it thinks can accept 4k video. As I understand it, this needs to be part of the HDMI handshake between the Rock 5b and the camera. I’ve tested with a 4k HDMI capture card, and when I connect to it I can switch the camera’s mode to 4k and receive the 4k video on the connected computer.

Is there any way to see or control the handshake data offered by the Rock 5b? Or is there something else I should try?

v4l2-ctl can do it. Check out v4l2-ctl --help-edid.

I think the default EDIDs included in the kernel image are for 1080p60 and 2160p30 (controllable at /sys/class/hdmirx/hdmirx/edid - values 1 and 2 are the builtins). v4l2-ctl has a 2160p60 edid included, and you can also load arbitrary EDIDs from other devices - I copy the 1440p60 one from my monitor and put it on the HDMI input.

Edit to add:

v4l2-ctl --set-edid type=hdmi-4k-600mhz,audio,ycbcr444,ycbcr422,fl-fr

Should make your HDMI input show up as 2160p60 (4k), with PCM audio input on 2 channels marked front-left and front-right.

2 Likes

That worked! Thank you Sarah, that would have taken me a very long time to figure out on my own.

1 Like

A bit of curiosity here: is audio captured correctly from your camera?

I’m trying to send the audio stream out to speakers and it sounds like it’s been slowed down slightly.

Audio is next on my list, but I’ve never managed to get it working previously. “Slightly slowed down” would make me suspect (baselessly) that it’s captured at 48 khz and interpreted as 44.1 khz.

I’ll let you know if I have any luck getting it working this weekend!

So I played around with video capture a bunch more today. I got sound working fairly easily, and it sounds pretty reasonable to my ears. Here’s the gstreamer command that’s working for me:

gst-launch-1.0 -e v4l2src device=/dev/video0 ! video/x-raw,format=BGR,width=3840,height=2160 ! queue ! mpph265enc ! h265parse ! queue ! mux. alsasrc device=hw:3,0 ! audio/x-raw,channels=2 ! audioconvert ! voaacenc ! queue ! mux. matroskamux name=mux ! filesink location="/storage/hdmi4s_$(date +"%Y%m%d_%H%M%S").mkv"

I occasionally get the message that sound buffers were dropped, which is a problem I need to look into. I started with lamemp3enc and experimented with vorbis as well, but the dropped buffers message is least frequent with voaacenc.

The problem that consumed most of my time is that I’m seeing corrupt frames from time to time. sometimes it’ll be roughly every 10th frame, sometimes it’ll go a minute or two without one. And the corruption is very specific: the frame will look correct at the top, and then somewhere part of the way down it’ll switch to what appears to be an old frame from many frames ago (further back than the previous frame).

This happens even with a simple pipeline that encodes frames to h265 or h264 and dumps them directly to a file, so I suspect it’s happening in v4l2, perhaps as a result of connection / cable / interference issues. So my next step will be to try swapping out the HDMI cable a few times and see if it helps.

This issue is interesting because I can’t find anyone else reporting the same, yet I feel like I’ve seen various instances of it constantly - when working with v4l2 and webcams on a Raspberry Pi (where I would expect USB to retry if there were link issues - does HDMI do the same?), and I’ve also seen it very occasionally when working with Luxonis cameras that encode to h265 on device - it’ll show a single previous or torn frame without the weird artifacts you’d expect if the frame was encoded prior to being corrupted or reordered.

My wild guess is that these systems use a series of buffers for frames writing to them in series and then looping back to the beginning. If the writing to a particular buffer gets interrupted for some reason you’ll end up with a frame that starts with the current frame and then transitions to the last frame that was written to the buffer. So e.g. if there are 10 frame buffers and the writing gets interrupted 1/3 of the way through, you’ll end up with the current frame covering the top 1/3 of the screen and the old frame (from 10 frames back) covering the bottom 2/3 of the screen.

@Sarah have you run into anything similar? Maybe I’m just searching badly, but I’m surprised that I’m encountering this in so many different systems and yet I can’t find anyone talking about it.

Found this: https://obsproject.com/forum/threads/v4l2-multiplanar-support-rockchip-mpp-encoder-rga-for-rk3588-native-4k60-hdmi-input.161205/ (modified it a bit to work for me)

Audio playback now seems to sound normal

gst-launch-1.0 -e v4l2src device=/dev/video0 ! 'video/x-raw,format=NV16,width=3840,height=2160' ! tee name=t t. ! mpph265enc ! h265parse ! matroskamux name=mux ! filesink location=videoandaudio.mkv sync=false alsasrc device=hw:3,0 ! opusenc ! mux. t. ! queue leaky=1

I haven’t encountered that yet - but that sounds like a reasonable explanation for it. I’m running with as minimal of buffer sizes as I can get, and also pretty much just sending the frames directly to screen, so…

Also, I did get audio working well - I’ve stuck, for the moment, to using qv4l2 for my usage, but it forces audio to 44.1kHz even though the stream is 48kHz - oops. I would just be using GStreamer entirely but it really doesn’t want anything to do with the NV24 color space except for slow conversion to another as far as I’ve been able to push it yet. :woman_shrugging: