Answers.Body: <p>I've since resolved this; the key was replacing the <code>-r &quot;${input_framerate}&quot;</code> in the second line of the <code>ffmpeg</code> invocation with <code>-framerate &quot;${input_framerate}&quot;</code>.</p>
  <p>The differences between these options is nicely described within <a href="https://stackoverflow.com/questions/51143100/framerate-vs-r-vs-filter-fps/51224132">this</a> answer.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-31T00:07:04.910Z
Answers.LastActivityDate: 2023-01-31T00:07:04.910Z
Answers.UserDisplayName: steeps
Body: <p>I have a video device and an audio device I'm trying to record from, as below:</p>
  <pre><code>$ 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)
  </code></pre>
  <p>and</p>
  <pre><code>$ 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
  </code></pre>
  <p>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:</p>
  <pre><code>#!/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 &quot;${input_resolution}&quot; -r &quot;${input_framerate}&quot; -thread_queue_size &quot;${v4l2_thread_queue_size}&quot; -hwaccel vaapi -hwaccel_device my_intel_gpu -hwaccel_output_format yuv420p -i /dev/video0  \
         -f alsa -thread_queue_size &quot;${alsa_thread_queue_size}&quot; -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 \
         &quot;file:output.mkv&quot;
  </code></pre>
  <p>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 <a href="https://youtu.be/Zat9CRfUr-E?t=62" rel="nofollow noreferrer">'Benny Hill'-style effect</a>.</p>
  <p>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.</p>
  <p>Thanks in advance.</p>
  
Tags: <ffmpeg>
Title: FFmpeg v4l2 recording - variable frame rate output
UserDisplayName: steeps
ThreadText: # FFmpeg v4l2 recording - variable frame rate output
  
  (Asked by: username_0 on 2022-09-18)
  
  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](https://youtu.be/Zat9CRfUr-E?t=62).
  
  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.
  
  **Tags:** ffmpeg
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2023-01-31. Score: 0 | Accepted answer
  
  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](https://stackoverflow.com/questions/51143100/framerate-vs-r-vs-filter-fps/51224132) answer.
  
  
  ---
  
  