0

I have a video device and an audio device I'm trying to record from, as below:

$ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
    Type: Video Capture

    [0]: 'MJPG' (Motion-JPEG, compressed)
        Size: Discrete 1280x720
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 960x540
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 848x480
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
    [1]: 'YUYV' (YUYV 4:2:2)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 424x240
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 320x180
            Interval: Discrete 0.033s (30.000 fps)
        Size: Discrete 160x120
            Interval: Discrete 0.033s (30.000 fps)

and

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC289 Analog [ALC289 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

I'm using ffmpeg, with the mjpeg input stream for the video, and hardware acceleration to encode it as h.265, along with flac encoding for the audio:

#!/usr/bin/env bash

input_framerate=30
input_resolution=hd720

v4l2_thread_queue_size=32
alsa_thread_queue_size=8192

ffmpeg -init_hw_device vaapi=my_intel_gpu:/dev/dri/renderD128 \
       -f v4l2 -c:v mjpeg -input_format mjpeg -video_size "${input_resolution}" -r "${input_framerate}" -thread_queue_size "${v4l2_thread_queue_size}" -hwaccel vaapi -hwaccel_device my_intel_gpu -hwaccel_output_format yuv420p -i /dev/video0  \
       -f alsa -thread_queue_size "${alsa_thread_queue_size}" -i hw:0 \
       -vf 'format=nv12,hwupload' -c:v hevc_vaapi -rc_mode ICQ -qp 24 \
       -af 'aresample=async=1000' -c:a flac -compression_level:a 3 \
       "file:output.mkv"

This works well in a well-lit environment, but if I don't have sufficient light, the framerate drops on the camera, but not in the resulting video: the output still plays at the input framerate, speeding up and giving a 'Benny Hill'-style effect.

How do I ask ffmpeg to output a 'constant-speed'/'variable frame rate' recording? I've tried doing video on its own, excluding audio, as well as using unaccelerated hevc, but these suffer from the same issue.

Thanks in advance.

1 Answer 1

0

I've since resolved this; the key was replacing the -r "${input_framerate}" in the second line of the ffmpeg invocation with -framerate "${input_framerate}".

The differences between these options is nicely described within this answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.