Video recorded with ffmpeg and HDMI to USB device at 1280×1024 is stretched (AR incorrect)

I would like to record a video of the screen of another PC with an HDMI to USB video capture card with ffmpeg, in Windows. I’m duplicating the PC screen on the second (virtual) monitor created by the HDMI Video Capture device and the screens resolution is 1280×1024.

The device supports that resolution:

C:\ffmpeg>ffmpeg.exe -hide_banner -f dshow -list_options true -i video="MyVideoDeviceName" 2>&1 | findstr "mjpeg.*1280x1024"
[dshow @ 0000017d0f699e40]   vcodec=mjpeg  min s=1280x1024 fps=10 max s=1280x1024 fps=60.0002
[dshow @ 0000017d0f699e40]   vcodec=mjpeg  min s=1280x1024 fps=10 max s=1280x1024 fps=60.0002

So I try to record a short video of an image displayed in full screen with this command:

C:\ffmpeg>ffmpeg.exe -hide_banner -y -f dshow -rtbufsize 100M -video_size 1280x1024 -framerate 30 -vcodec mjpeg -i video="MyVideoDeviceName":audio="MyAudioDeviceName" -vcodec libx264 -b:v 7000k -acodec aac test.mp4

Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, dshow, from 'video=MyVideoDeviceName:audio=MyAudioDeviceName':
  Duration: N/A, start: 1533.874000, bitrate: N/A
    Stream #0:0: Video: mjpeg (Baseline) (MJPG / 0x47504A4D), yuvj422p(pc, bt470bg/unknown/unknown), 1280x1024, 30 fps, 30 tbr, 10000k tbn, 10000k tbc
    Stream #0:1: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (pcm_s16le (native) -> aac (native))
Press [q] to stop, [?] for help
Output #0, mp4, to 'test.mp4':
  Metadata:
    encoder         : Lavf58.31.104
    Stream #0:0: Video: h264 (libx264) (avc1 / 0x31637661), yuvj422p(pc, progressive), 1280x1024, q=-1--1, 7000 kb/s, 30 fps, 10000k tbn, 30 tbc
    Metadata:
      encoder         : Lavc58.55.101 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/7000000 buffer size: 0 vbv_delay: 18446744073709551615
    Stream #0:1: Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s
    Metadata:
      encoder         : Lavc58.55.101 aac
frame=   74 fps= 34 q=-1.0 Lsize=    1247kB time=00:00:02.36 bitrate=4318.0kbits/s dup=4 drop=0 speed= 1.1x

If I stop the capture with Q and check the details of the test.mp4 file with mediainfo it seems correct:

General
Complete name                            : test.mp4
Format                                   : MPEG-4
Format profile                           : Base Media
Codec ID                                 : isom (isom/iso2/avc1/mp41)
File size                                : 1.22 MiB
Duration                                 : 2 s 467 ms
Overall bit rate mode                    : Variable
Overall bit rate                         : 4 142 kb/s
Writing application                      : Lavf58.31.104

Video
ID                                       : 1
Format                                   : AVC
Format/Info                              : Advanced Video Codec
Format profile                           : High 4:2:2@L3.2
Format settings                          : CABAC / 4 Ref Frames
Format settings, CABAC                   : Yes
Format settings, Reference frames        : 4 frames
Codec ID                                 : avc1
Codec ID/Info                            : Advanced Video Coding
Duration                                 : 2 s 467 ms
Bit rate                                 : 4 029 kb/s
Nominal bit rate                         : 7 000 kb/s
Width                                    : 1 280 pixels
Height                                   : 1 024 pixels
Display aspect ratio                     : 5:4
Frame rate mode                          : Constant
Frame rate                               : 30.000 FPS
Color space                              : YUV
Chroma subsampling                       : 4:2:2
Bit depth                                : 8 bits
Scan type                                : Progressive
Bits/(Pixel*Frame)                       : 0.102
Stream size                              : 1.18 MiB (97%)
Writing library                          : x264 core 158 r2984 3759fcb
Encoding settings                        : cabac=1 / ref=3 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=30 / lookahead_threads=5 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=250 / keyint_min=25 / scenecut=40 / intra_refresh=0 / rc_lookahead=40 / rc=abr / mbtree=1 / bitrate=7000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00
Color range                              : Full
Codec configuration box                  : avcC

Audio
ID                                       : 2
Format                                   : AAC LC
Format/Info                              : Advanced Audio Codec Low Complexity
Codec ID                                 : mp4a-40-2
Duration                                 : 2 s 43 ms
Bit rate mode                            : Variable
Bit rate                                 : 123 kb/s
Maximum bit rate                         : 128 kb/s
Channel(s)                               : 2 channels
Channel layout                           : L R
Sampling rate                            : 44.1 kHz
Frame rate                               : 43.066 FPS (1024 SPF)
Compression mode                         : Lossy
Stream size                              : 30.7 KiB (2%)
Default                                  : Yes
Alternate group                          : 1

The problem is when I play the video… it is stretched in the middle, with black bars on the right and the left. Here’s a resized screenshot:

Resized screenshot of the recording

I’ve tried a bunch of other ffmpeg settings, such as -aspect 5:4 and -vf "scale=1280:1024,setdar=5/4" but I’m not able to get the pixels cover the complete resolution, as it is in the original screen. I suspect it’s due to the HDMI capture device, but I cannot change the screen resolution to 1920×1080 and, according to what seen before, 1280×1024 is a supported resolution.

How can I teach ffmpeg to capture the video correctly? The best result I got is by cropping an amount of left/right pixels identified by trial and error. After adding -vf "crop=iw-360:ih,scale=1280:1024" I see this:

Resized screenshot of the recording with a cropped width

But, of course, the scaling blurs the image a little and the value 360 is not determined mathematically.

Read more here: Source link