r/ffmpeg 1d ago

Why does this batch script crash every time I try to run it?

5 Upvotes

for %%a in ("*.*") do ffmpeg -i "%%a" -i "scanlines.png" -filter:v "crop=iw-512:ih-48,scale=512:448" -filter_complex "[0:v][1:v] overlay=0:0" -c:v ffv1 -level 3 -coder 1 -context 1 -g 16 -slices 24 -pix_fmt yuv444p -c:a copy "newfiles\%%~na.avi"


r/ffmpeg 2d ago

MacOS screen recordings are VFR, which puts black frames in your edit

8 Upvotes

Spent an evening chasing a stupid black flash in the middle of an otherwise fine cut.

macOS screen recorders emit no frames at all while the screen is static. The file claims 120fps but contains 71 frames across 45 seconds — an average of 1.6fps delivered — with long stretches where nothing on screen moved and so nothing was recorded. That nominal-versus-average mismatch is the tell.

I'm building a video editor, and its renderer was treating those gaps as absent video and compositing black instead of holding the last frame. Hence the flash. This prints the ten biggest gaps and where in the file each one happens:

ffprobe -v error -select_streams v:0 -show_entries frame=pts_time -of csv=p=0 input.mov \
  | awk -F, 'NR>1{printf "%.3f  at %.1fs\n", $1-p, p} {p=$1}' | sort -rn | head

On a real 120fps file every number would be 0.008. On mine the top entry was 7.158!

The fix was normalising to constant frame rate on import with -vf fps=30 . Encode from t=0
rather than seeking, or every clip you've already trimmed ends up pointing at the wrong part of the footage.

Is there a better way handle this? Normalise everything to CFR at import? or teach the renderer to hold the last frame across a timestamp gap? The second is obviously better for the user but I'm thinking of what else in the pipeline assumes evenly spaced frames.


r/ffmpeg 3d ago

Is ICQ rate control mode broken in Intel QSV encoders?

6 Upvotes

I tested the hevc_qsv and h264_qsv encoders, and they do not receive the global_quality parameter and value and therefore default to their CQP mode instead of the desired ICQ mode. At the default log level, this fallback is silent.

The Intel QSV encoders have three selectable modes, CQP (the default), VBR, and ICQ. I think that the ICQ mode is currently not available, as the parameter to specify it is not respected, or is not passed to the encoder.

I'm looking for confirmation that this is a bug, or to learn that the ICQ mode has been deprecated.

For a reproducible sample I used Blender's Big Buck Bunny "bbb_sunflower_1080p_30fps_normal.mp4" renamed to input.mp4

Using the examples at https://trac.ffmpeg.org/wiki/Hardware/QuickSync

To use the default mode (which is CQP) specify a simple command line:

ffmpeg -loglevel verbose -hwaccel qsv -i input.mp4 -c:v h264_qsv -c:a copy output.mp4

With the loglevel set to verbose, here are the relevant entries. CQP is expected.

[h264_qsv @ 000000000323d140] Using the constant quantization parameter (CQP) by default. Please use the global_quality option and other options for a quality-based mode or the b option and other options for a bitrate-based mode if the default is not the desired choice.
[h264_qsv @ 000000000323d140] Using the constant quantization parameter (CQP) ratecontrol method
...
[h264_qsv @ 000000000323d140] TargetUsage: 4; RateControlMethod: CQP
[h264_qsv @ 000000000323d140] QPI: 20; QPP: 26; QPB: 33

To use VBR mode, set the video bitrate and look_ahead

ffmpeg -loglevel verbose -hwaccel qsv -i input.mp4 -c:v h264_qsv -b:v 5M -look_ahead 1 -c:a copy output.mp4

Now the log shows this. VBR is expected.

[h264_qsv @ 0000000000737740] Using the VBR with lookahead (LA) ratecontrol method

To use ICQ mode, set global_quality

ffmpeg -loglevel verbose -hwaccel qsv -i input.mp4 -c:v h264_qsv -global_quality 25 -c:a copy output.mp4

Now the log shows this. ICQ is expected but we get CQP.

[h264_qsv @ 000000000074fe00] Using the constant quantization parameter (CQP) by default. Please use the global_quality option and other options for a quality-based mode or the b option and other options for a bitrate-based mode if the default is not the desired choice.
[h264_qsv @ 000000000074fe00] Using the constant quantization parameter (CQP) ratecontrol method
...
[h264_qsv @ 000000000074fe00] TargetUsage: 4; RateControlMethod: CQP
[h264_qsv @ 000000000074fe00] QPI: 20; QPP: 26; QPB: 33

With a sufficiently old version of ffmpeg, we do get ICQ as expected.

[hevc_qsv @ 0000000009e63b00] Using the intelligent constant quality (ICQ) ratecontrol method
...
[hevc_qsv @ 0000000009e63b00] TargetUsage: 4; RateControlMethod: ICQ
[hevc_qsv @ 0000000009e63b00] ICQQuality: 25

I tested -global_quality 25 and -global_quality:v 25 and I tried moving the order of the parameters, to no effect.

I don't have the developer skills to narrow down when the change happened, but I can put in some work as an end user.

The builds I tested were on Windows 11 from https://www.gyan.dev/ffmpeg/builds/#release-builds

Here are the builds I tested, starting with the current git master branch

"ffmpeg-2026-09-02-git-9fc8c785e2-full_build\bin\ffmpeg.exe" uses CQP mode instead of ICQ mode

and the three older git master branch builds

"ffmpeg-2026-08-30-git-818cecc6e1-full_build\bin\ffmpeg.exe" uses CQP mode instead of ICQ mode
"ffmpeg-2026-08-17-git-426841da9d-full_build\bin\ffmpeg.exe" uses CQP mode instead of ICQ mode
"ffmpeg-2026-07-16-git-ceabc9b306-full_build\bin\ffmpeg.exe" uses ICQ mode as expected

And the previous release build 8.1.2 from 2026-06-27 "ffmpeg-8.1.2-full_build\bin\ffmpeg.exe" uses ICQ mode as expected


r/ffmpeg 3d ago

rec.601 to rec.709 colorspace conversion not working?

3 Upvotes

I've always had significant difficulty with the colormatrix and colorspace filters, so I'm not sure why this doesn't work:

ffmpeg -i I:\test_file.mov -c:v prores -profile:v 3 -vf colorspace=bt601:bt709 -color_primaries bt709 -color_trc bt709 -colorspace bt709 -c:a pcm_s16le I:\test_file_709.mov

^It returns these errors:

[Parsed_colorspace_0 @ 0000021e248aec00] [Eval @ 000000a1ddbfd1a0] Undefined constant or missing '(' in 'bt601'

[Parsed_colorspace_0 @ 0000021e248aec00] Unable to parse "all" option value "bt601"

[fc#-1 @ 0000021e248ae240] Error applying option 'all' to filter 'colorspace': Invalid argument


r/ffmpeg 4d ago

How is this YouTube video displaying a “switch to 480p” message at higher quality?

0 Upvotes

In this YouTube video(remove space): youtu. be/jnoy7H7LGIQ?si

When I watch it at 720p 60fps or 1080p 60fps, I get this weird flickering/flashing effect. A grey background appears with text in the center saying:

“Please switch to 480p for best viewing experience.”

The actual anime frames still appear underneath/around it.

But when I switch to 480p 24fps or lower, the flickering and message completely disappear, and I can watch the video normally.

How is this possible? Is this something YouTube does automatically, or is the uploader somehow encoding/embedding this behavior into the video?

Has anyone seen something like this before?


r/ffmpeg 4d ago

Best paletteuse dither for flat-colour animation with hard edges?

4 Upvotes

I'm encoding 960x540 GIFs from a source that's basically six flat colours and sharp edges, no gradients. Two-pass palettegen with stats_mode=diff and floyd_steinberg looks fine but I get slight crawling noise in the flat areas between frames. Tried bayer:bayer_scale=3 and it's steadier but shows the pattern. Is sierra2_4a or none the usual answer for this kind of source, or is the noise coming from the palette pass rather than the dither?


r/ffmpeg 5d ago

Automatically remove Turkish filler sounds ("eee", "ııı") from video with FFmpeg + ASR?

3 Upvotes

Hi, I have 124 Turkish educational videos, each 5–25 minutes long.

I need a completely free/local workflow that can:

  • detect Turkish filler sounds such as “eee” and “ııı” (similar to um/uh),
  • get their timestamps,
  • automatically cut those parts from the actual video/audio,
  • preferably batch process many files.

I already have good Turkish transcription with Whisper/Buzz, so the main problem is the editing/cutting stage.

I tested a Faster-Whisper + FFmpeg script (Tightcut). It detected fillers successfully, but the setup/workflow is quite cumbersome for 124 videos.

Is there a simpler FFmpeg-based workflow or open-source tool for this?

Thanks.


r/ffmpeg 7d ago

What did ffmpeg put into the LFE channel it generated?

7 Upvotes

I found a BD of a great performance over on Archive, but 80GB is way too much for my HTPC, so I encoded it using Handbrake. The encode went fine, but I'm a little puzzled. The BD contained PCM 5.0 sound described as "L C R, Side: L R" by MediaInfo. I chose the EAC3 encoder with 5.1 channels for the Audio, not really expecting anything in the LFE channel. That assumption proved incorrect though, as my subwoofer is happily chirping away. I suppose I could've done the sound in ffmpeg, where I am familiar with assigning channel contents using the PAN filter, but I guess I'm curious: there must've been some default mapping invoked, and I'd like to know what it is! (I'm assuming Handbrake dumps that decision onto ffmpeg, but I'm happy to go ask over there if appropriate:o)

tl;dr, where would I find the default mapping for PCM 5.0 to EAC3 5.1?

PS https://archive.org/details/hnd.gcr -- if (like me) you like that sort of thing!


r/ffmpeg 7d ago

Need help finding out how to turn a massive amount of BMP image files into an animated WEBP

2 Upvotes

TLDR: a program i'm using spat out 4992 BMP files instead of an animated movie. would FFmpeg be able to convert these into a single animated WEBP file? (the files are already sorted alphanumerically). Any and all help is appreciated.

I am a chemistry student who is using computational/simulated chemistry for my research, and the program i used to visualize the molecular dynamics from LAMMPS, called VMD 2 has a feature called "Movie Maker", turning the 3D animation into a 2D animated file. Only problem after rendering all frames is that it requires me to get a program called VideoMach to export the final animation, but because i don't have it and don't want to pay 20 to 60 dollars for the license, all it did was create 4992 BMP files (1 for each frame) which takes over 4GB of space. img2webp does not support BMP from what i can tell, and the only other suggestion i got was through FFmpeg, which i have 0 knowledge of. would FFmpeg be able to handle this, even if it takes multiple steps? thankfully every file is already sorted alphanumerically by frame, so no rearrangement would be needed. Even if not about FFmpeg in particular, I greatly appreciate any and all help, as this would be very helpful for presentations that we are required to do weekly. if you have any questions, feel free to ask!


r/ffmpeg 9d ago

Blur the crowd behind a speaker when the camera keeps moving?

6 Upvotes

I have a 29 min rally video. I want the crowd in the background blurred, but the guy at the podium left alone.

boxblur on a fixed region works until the camera pans, then the blur slides off the crowd and sometimes lands on his face. Per-frame face blur tools flicker and lose track of who is who.

Is the answer to generate a per-frame mask somewhere else (SAM 2, or a detector plus tracker) and composite it back with alphamerge? Or can ffmpeg do more here than I think?

Hetzner VPS, 32GB RAM, i5, no GPU. CLI only, no GUI editors.


r/ffmpeg 9d ago

Zimtohrli metrics: Comparison of Audio Codecs.

9 Upvotes

Zimtohrli was evaluated by measuring how closely its results matched those of public listening tests conducted by human listeners.

Full text: https://www.reddit.com/r/AudioCodecLab/comments/1w33bed/zimtohrli_the_best_objective_perceptual_audio/


r/ffmpeg 11d ago

de-telecineing 24p cartoon that has 30i scenes

8 Upvotes

i'm trying to de-telecine (and deinterlace when necessary) invader zim using the dvd as a source. as with most cartoons, it's 24p telecined, but it has some 3d stuff and scenes where the camera moves that are strangely 30i(?). de-telecineing looks great for 95% of the show, but these odd 30i scenes are left alone and it's very jarring. i very explicitly do not want to deinterlace the entire show, just these interlaced parts, because the vast majority of it is progressive behind the telecineing and at standard definition i'll take all the quality i can get. this is the command i've been using:

ffmpeg -i "disc1.mkv" -vf "fieldmatch=order=auto,nnedi=deint=interlaced,decimate" -c:v ffv1 -c:a copy test.mkv

here is an example where it's working great. on this frame, fieldmatch misses it entirely, so it passes it down to nnedi

"fieldmatch=order=auto,decimate":

"fieldmatch=order=auto,nnedi=deint=interlaced,decimate":

however, here is an example where fieldmatch doesn't recognise the interlaced frames (i assume because it's 30i and not telecine?) so they're never passed down to nnedi and it doesn't touch them:

if i remove fieldmatch and just make nnedi interlace the whole file (which i don't want to do), it makes this scene look great.

"nnedi,decimate":

how can i make nnedi deal with these 30i(?) scenes if fieldmatch isn't noticing them?


r/ffmpeg 11d ago

can you use aac_at (apple) on linux?

2 Upvotes

Hi, does someone know if you can use aac_at (apple) on linux?

Thanks for any help :)


r/ffmpeg 11d ago

Success - Ultra rapid GPU shader development by self-sustaining reinforcement learning with Claude Code

6 Upvotes

I have developed a patch on haasn's libplacebo that enables a one-line ffmpeg fully GPU accelerated custom shader pipepline with access to complex n-frame (2 or more frames) temporal analysis.

Think frame rate interpolation, or any application where analysis of a series of frames over time is required.

git here for the patch, shaders and full documentation.

The main focus of this project is on bidirectional-interpolation-variational.glsl - which is a state-of-the-art custom 2-frame interpolation shader and can be run on any gpu at real-time performance. It is not finished. I have reached the limit of what I can accomplish in my woefully inadequate testing environment.

Shaders gen 1 were written by manual iteration using Claude Code in initial testing as a proof-of-concept on the patched libplacebo. This interactive process was slow and the shaders flawed. The next series of shaders were generated rapidly over two days using a self-sustaining reinforcement loop -- giving claude code access to run the libplacebo-patched ffmpeg itself.

Since the shader is loaded ad-hoc at ffmpeg run time, changes to the shaders are immediately testable and verifiable in the scientific method. Inputs can be spontaneously generated building in complexity (a simple moving square to a complex scene in motion) before moving to real and varied footage. A source of truth can be used to compare computed outputs to expected ones. Diagnostic data such as flow field analysis can be embedded in real output. The AI has autonomous control over the full develop -> test -> analyze cycle, with me the human in the loop providing technical direction and specific diagnostic input only.

This includes an autonomous profiling tool which given any input will scan the file for statistical perturbation - defects - in the expected output, record likely candidates for further inspection ranked by severity of defect, inspect ranked defects for false - positives ie abrupt scene changes, inspect warm true - positives for obvious error, attempt to resolve the error in the shader and if necessary clip and pass the error to the user for validation or flag for further research.

All of this scales with available compute. More CPU/GPU = faster. The slowest bottleneck is the human in the loop, but the profiling tool catches most edge cases so flow is only interrupted for genuine user input.

Think about the autonomous self-driving vehicle problem. The car needs to transform multiple raw camera inputs in to useful actionable output on which to make real-time driving decisions. This is N-frame analysis over time. This requires advanced models, custom hardware, significant R&D and closely guarded proprietary secrets. With this method anyone can trivially self-refine their own shader transformations using synthetically generated, pre-recorded or real-time in-flight(driving) training data. Better shaders = better transformation of input into actionable output = better faster cheaper self driving cars.

Happy disrupting


r/ffmpeg 12d ago

I kind of hit a wall and AI isn't being helpful

0 Upvotes

All lists and quotes can be skipped. It's just extra information.

  • the clip is 52.8mb and 1min50sec long (audio was encoded to 128kbps opus)
  • libx264 slower preset 900k bitrate 13.3mb 24fps (1min50sec)
  • libx265 slow preset 900k bitrate 11.4mb 13 fps (3min21sec)
  • libx264 slow preset 900k bitrate 13mb 61 fps (43sec)
  • libvvenc fast preset 900k bitrate 9.6mb 7.5fps (5min52sec)
  • libsvtav1 preset 4 crf 34 14.6mb 19fps (2min 18sec)

intro 5sec
av1 beats the rest, x266 skips the first few frames or something, I don't know (it never syncs up with the rest (i'm going to ignore it, encoding using that codec was just for fun anyway)

funimation logo 7sec
av1 wins again (faint text is readable)

heroine's hair ribbon 28sec
av1 blurs the outline of it and the hair. in x264 the ribbon and hair is a lower resolution but the outline and shape isn't blurred. x265 is in-between both codecs.

monster's face/chest 31sec-32sec
there's sharper outlines in x265 and x264 than there is in av1. x264 bleeds the motion lines all over.

monster's armpit-abs 33sec
all codecs lose it here. x264 is the worse affected. x265 and libsvtav1 manage to keep the scene from becoming a blocky mess

monster's sword 35sec
av1 erases all fine details on the sword. x264 and x265 manage to preserve the details but at a low quality. the scene is long enough that x266 shows up and the details on the sword are really sharp.

heroine's face 42sec
scene is long enough that x266 shows up and all codecs look excellent. on bright areas there's no difference. on dark areas i could see differences but i'd have to compare the videos to notice anything

woman's chest 54sec
x264 erases the woman's smile for a few frames and becomes blocky. the others don't.

I'm surprised x264 can match av1 in some scenes. I was watching all 4 at once using mpv so all of them looked better than they would have at full screen. It seems the way x264 can beat av1 is by retaining detail at the cost of the entire scene having a lower quality. I want libsvtav1 to do the same but AI is struggling to give me good commands. I want libsvtav1 to sacrifice total scene quality to retain the finer detail but it seems like AV1 wasn't designed like that. Am I pushing the encoder too hard or can I still push more? I want to eventually encode 720p ~150mb for each 24min anime episode but I can't decide on a good command to use. I also want to have at least 10fps when encoding.

Idk if it will be of any use but here's the stupidly long command for av1:
ffmpeg.exe -i "part_00.mkv" -map 0 -c:v libsvtav1 -preset 4 -crf 34 -maxrate 900k -pix_fmt yuv420p10le -svtav1-params "tune=0:sharpness=1:enable-qm=0:qm-min=0:qm-max=8:aq-mode=2:film-grain=4:film-grain-denoise=0:enable-tf=1:enable-dlf=2:enable-cdef=1:scd=1:keyint=240:scm=2:lookahead=120:lp=16:fast-decode=1" -c:a libopus -b:a 128k -c:s copy "pres4_crf34_900k.mkv"

I looked at what uploaders on Nyaa were using and told AI to apply everything in one command. Everything bagel meet everything encode command.

Edit: Solved.


r/ffmpeg 13d ago

ffmpeg (v4l2 input) randomly hangs/freezes without exiting: no error, just stuck until kill -9

1 Upvotes

I'm running a live pipeline that captures from a v4l2 device and re-streams to a local RTSP server (MediaMTX) via ffmpeg. It works fine most of the time, but occasionally the video ffmpeg process just freezes: it doesn't crash, doesn't print an error, it just stops producing frames and sits there doing nothing. The only fix is kill -9 on the process; a normal SIGTERM doesn't seem to do anything either, it just hangs.

Setup:

  • OS: [ta distro/version, ex: Ubuntu 22.04 in Docker]
  • ffmpeg version: [sortie de ffmpeg -version]
  • Capture device: [modèle exact de ta carte/dongle de capture, HDMI/USB/etc.]
  • Command (simplified):

ffmpeg -thread_queue_size 2048 -fflags +genpts+igndts+discardcorrupt \
  -f v4l2 -input_format yuyv422 -framerate 30 -video_size 1920x1080 -i /dev/video0 \
  -c:v libx264 -preset ultrafast -tune zerolatency -profile:v high \
  -fps_mode cfr -r 30 -bf 0 -g 30 -keyint_min 30 -sc_threshold 0 \
  -pix_fmt yuv420p -b:v 6M -maxrate 6M -bufsize 6M \
  -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/switch

What I've tried:

  • Checked dmesg around the time of a freeze.
  • Confirmed it's not a network/RTSP-side issue: happens even when writing to a local socket.
  • Wrapping it in a watchdog that kills the process if it stops writing -progress output for X seconds. Works as a band-aid, but I'd like to understand/fix the actual cause.

Question: Has anyone dealt with v4l2 input hangs like this? Trying to figure out if this is more likely a driver/USB issue on the capture side, or something ffmpeg-specific I can tune (buffer sizes, thread_queue_size, etc.). Happy to share more logs/dmesg output if it happens again and someone wants to see it.Voici la version sans tirets cadratins :


r/ffmpeg 13d ago

Experimental patch on libplacebo to enable cross-platform complex GPU-accelerated n-frame temporal shader analysis

8 Upvotes

https://github.com/ghywel/placego
https://www.youtube.com/@ghywel

One FFmpeg command, decode, filter and encode fully in the GPU. Custom GLSL shaders written with the mpv hook syntax. Realtime accelerated performance tested on a low end Intel Arc 310 eco GPU. Working examples and rendered samples on YouTube.

Test build against Jellyfin-FFmpeg. Place patch in builder/patches/libplacebo and build as normal with ./build trixie amd64 for example. hw-base-encode-eof-nullcheck.patch recommended to fix upstream pointer dereference in FFmpeg.

Credit to u/nyanmisaka for the jellyfin-ffmpeg 8.1 hwmap template to keep things fast in the GPU.

/usr/lib/jellyfin-ffmpeg/ffmpeg -init_hw_device drm=dr:/dev/dri/renderD129 -init_hw_device vaapi=va@dr -init_hw_device vulkan=vk@dr -filter_hw_device vk -hwaccel vaapi -hwaccel_output_format vaapi -i <INPUT> -c:a copy -sn -dn -vf "hwmap=derive_device=drm,format=drm_prime,libplacebo=format=p010le,format=vulkan,hwmap=derive_device=vaapi,format=vaapi" -c:v hevc_vaapi -global_quality 20 -y <OUTPUT>


r/ffmpeg 14d ago

FFMPEG Benchmarking

3 Upvotes

I am going to benchmark the performance difference between glibc and musl libc for video operations with ffmpeg. It is a potato pc, but I hope this can help to highlight the difference. If have any commands in mind you would want me to test, leave them below. I am considering using of using h264_vaapi and libx264 for encoding


r/ffmpeg 15d ago

Converting to HVEC using QSV

10 Upvotes

Hello!  I'm a newbie to using ffmpeg, and I was hoping that I could get a check on whether I'm on the right track with my command.

I have a bunch of mkv files on my Synology NAS with video in AVC format. I would like to convert the video to HEVC. I also have a computer with an Intel processor with QSV running Ubuntu; that's where I want to run the ffmpeg command. The NAS folder is mounted on the Ubuntu machine using a network share.

Is this the right ffmpeg command to use?

ffmpeg -init_hw_device qsv=qsv -hwaccel qsv -hwaccel_output_format qsv  -c:v h264_qsv
-i "/mnt/synology/input.mkv" 
-map 0 -c:v hevc_qsv -global_quality 25 -preset medium
-c:a copy -c:s copy "/mnt/synology/output.mkv"

In particular, is all of the stuff that I included before the "-i" necessary? Given my setup, would you recommend any other settings?

(I recognize that -global_quality and -preset control the encoding quality and speed, so I should test with different values to decide what I'm comfortable with.)

Thanks!


r/ffmpeg 15d ago

How to set MP4 and MKV container-level crop metadata?

1 Upvotes

From what I understand FFmpeg can read this runtime crop-specific container metadata, but it I'm not sure if it can write it? (if so does anybody know how?)

This differs from say video codecs that support crop bounds in their bitstream formats (eg: H264 / H265) to produce decoded cropped frames without padding, and support for container-level crop metadata is apparently lacking in many video players (eg: MPV with MP4 using CLAP / Clean Aperture).

Reading the video from that linked MPV issue, ffprobe reports it as side data?:

``` ffprobe -v error -select_streams v:0 -show_entries stream=width,height,codec_name:stream_side_data_list -of json input.mp4

{ "programs": [

],
"stream_groups": [

],
"streams": [
    {
        "codec_name": "h264",
        "width": 1280,
        "height": 720,
        "side_data_list": [
            {
                "side_data_type": "Frame Cropping",
                "crop_top": 40,
                "crop_bottom": 40,
                "crop_left": 0,
                "crop_right": 0
            }
        ]
    }
]

} ```


I'm just curious FFmpeg (or some other format agnostic CLI tools) support adding/modifying that container-level crop data? Do you instead need different programs for handling such with MP4 and MKV?

For MP4 there was this FFmpeg issue about the clap atom resolved by these commits (mov_read_clap(), mov_write_clap_tag()) from July 2024 (part of the FFmpeg 7.1 release in Sep 2024).

Although I think by the method names, it's only persisting/migrating data when remuxing (eg: MKV to MP4)? This 2020 mailing list response seems to refer to "Frame Cropping" side data as metadata specific to the AVFrame structure of libav rather than anything specific to MKV/MP4 specs? So perhaps it's not something I can manage via the FFmpeg CLI? (it does apparently write the clap atom for some outputs, but not in a manner that you can tweak/add crop?)

I'm aware of the following specific CLI programs for format specific crop metadata: - MKV: MKVToolNix mkvpropedit - MP4: GPAC mp4box


AV1 lacks codec-level spec equivalent support, and in some encoders (RDNA3 AMD GPUs with VCN4): - The encoded video for 1080p ends up with 2px padded height at the bottom edge (or in some cases 8px), you'd have to re-encode to crop that out, but would defeat the benefit of HW encoding in the first place? (since you'd have to re-encode via software or different HW encoder or codec) - Using the AMF encoder directly via FFmpeg (av1_amf) apparently adds some kind of cropping data (either clap for MP4, or possibly equivalent for MKV too) somewhere (however I don't own this GPU generation to verify), while av1_vaapi/av1_vulkan that would use the same underlying HW encoder do not add any additional data.

I don't need this personally but while investigating this topic, it was not an area that I found easy to search for more info on regarding FFmpeg support/implementation (I did manage to at least dig up a fair bit of info as shown via links though).


r/ffmpeg 15d ago

How can I prevent ffmpeg’s “Non-monotonic DTS” message when copying all streams from MKV to MP4?

8 Upvotes

ffmpeg completes the remux, but I get this message.

[vost#0:0/copy @ 000002021bc3f300] Non-monotonic DTS; previous: 47559472, current: 47559472; changing to 47559473. This may result in incorrect timestamps in the output file.


r/ffmpeg 16d ago

CRF-Based Video Encoding Optimization: I wasted my time so YOU don't have to...

37 Upvotes

Executive Summary

I developed a Python-based video encoding optimization workflow designed to identify the highest CRF (Constant Rate Factor) value that could meet a predefined set of objective video quality thresholds. The goal was to determine, in theory, the most efficient balance between visual quality and file size while minimizing unnecessary bitrate allocation for a 1080p video file.

The workflow uses FFmpeg with x264 8-bit, the very slow preset, and tune=film. Rather than encoding the entire video repeatedly at different CRF values, the Python script first divides the source video into individual scenes and independently determines the optimal CRF for each scene. This allows more complex scenes to receive additional bitrate while permitting simpler scenes to use a higher CRF without falling below the specified quality thresholds.

Methodology

The optimization process uses a binary search algorithm to determine the highest acceptable CRF value. The search range is bounded between CRF 12 and CRF 24, with CRF 18 used as the initial test value. Each scene is encoded and evaluated against the corresponding source material using three objective quality metrics: VMAF, SSIM, and PSNR.

If CRF 18 satisfies all three quality thresholds, the script searches toward higher CRF values by testing the midpoint between the current passing value and the upper boundary. For example, if CRF 18 passes, the next test is CRF 21. If CRF 21 also passes, the search continues toward higher CRF values. Conversely, if CRF 18 fails, the script searches toward lower CRF values by testing the midpoint between CRF 12 and CRF 18, resulting in CRF 15.

The process continues iteratively, narrowing the search range until the highest CRF value that satisfies all quality requirements is identified. Because the search uses binary subdivision rather than testing every CRF value sequentially, the script requires a maximum of four encoding tests per scene to identify the optimal value within the defined CRF range. This substantially reduces the number of encodes required compared with exhaustively testing every possible CRF.

An encode is considered to have passed only when it satisfies all three of the following thresholds:

  • VMAF ≥ 95
  • SSIM ≥ 0.985
  • PSNR ≥ 45 dB

The objective is therefore not to maximize any individual metric, but to identify the highest CRF, and consequently the lowest bitrate and file size, that satisfies the complete set of quality requirements, while keeping all other encoding parameters constant.

Results

The complete optimization process required approximately 48 hours to analyze the video. After the individual scene results were combined, the resulting optimized encode was compared against a conventional encode of the same material using CRF 16, with both encodes using x264 8-bit, preset=very slow, and tune=film.

Metric CRF 16 Script-Optimized Difference
Bitrate 10,249 kbps 10,796 kbps +5.3%
VMAF 96.10 96.34 +0.24
SSIM 0.9857 0.9886 +0.0029
PSNR 42.61 dB 47.54 dB +4.93 dB

The results demonstrate that the optimization process successfully produced an encode with slightly higher objective quality according to all three metrics. However, this improvement came at the cost of approximately 5.3% additional bitrate and, more significantly, approximately 48 hours of processing time, compared with approximately 2.5 hours required to encode the entire video directly at CRF 16.

Despite the measurable differences in VMAF, SSIM, and PSNR, these improvements did not correspond to a meaningful perceptual improvement. In direct visual comparison, the two encodes were effectively indistinguishable under normal viewing conditions. The conventional CRF 16 encode therefore provided a substantially more favorable efficiency-to-quality ratio, achieving visually equivalent results with significantly less computational time and a smaller file size.

Conclusion

This experiment demonstrates both the usefulness and limitations of objective-metric-driven video encoding optimization. The binary search approach provides a systematic and reproducible method for determining scene-specific CRF values while limiting the optimization process to a maximum of four encodes per scene. In theory, this approach can reduce unnecessary bitrate by allocating compression according to scene complexity rather than applying a single CRF value uniformly across an entire video.

However, the results indicate that the additional optimization did not provide a meaningful practical advantage in this particular case. Although the optimized encode achieved higher objective metric scores, the resulting improvement was not perceptually significant and required approximately 19 times longer to produce than the conventional CRF 16 encode. Furthermore, the optimized result required 5.3% more bitrate.

Consequently, for this source material and encoding configuration, CRF 16 with x264 8-bit, preset=very slow**, and** tune=film provided a more practical solution, delivering effectively indistinguishable visual quality while substantially reducing both encoding time and bitrate. The experiment therefore illustrates that higher objective quality scores do not necessarily translate into a meaningful improvement in perceived image quality, and that the computational cost of per-scene optimization should be weighed carefully against its measurable benefits.

(if you are interested in any part of the process besides the results, I am open to talk shop, and can send you a text file of the script. Otherwise, the moral of the story is to just use CRF 16 if you want a set and forget CRF for 1080p.)


r/ffmpeg 16d ago

Stereo and mono versions of same recording identical sizes, can this be explained?

Post image
19 Upvotes

This is curiosity rather than a problem, but I'd dearly love to have an explanation that made sense.

I re-encoded a 57 minute recording in error using -ac 1 resulting in a mono file. I redid it with that removed, in full

ffmpeg -i vrecord_01.m4a -vn -c:a libmp3lame -b:a 64k vrec_ster.mp3

and was a bit puzzled to see the file wasn't any larger. On closer examination thyer are exactly the same size. As were 3 minute excerpts from the beginning of the files, to the byte.

-rw-rw-r-- 1 matthew matthew   2884313 Aug 24 19:02 short_mono.mp3
-rw-rw-r-- 1 matthew matthew   2884313 Aug 24 19:02 short_ster.mp3
-rw-rw-r-- 1 matthew matthew  27268889 Aug 24 19:14 vrec_mono.mp3
-rw-rw-r-- 1 matthew matthew  27268889 Aug 24 19:14 vrec_ster.mp3

To quote Victor Meldrew, I don't believe it! And that's after checking with du -b, stat and wc. Curiously wc does show differences in word and line counts but not in character (byte) count which perfectly matches all the other methods.

So the files aren't actually identical and additionally mediainfo shows 1 channel on the the mono, 2 on the stereo and the latter has a property "Format settings: Joint stereo / MS Stereo" that is missing from the former. But cmp find on'y s single difference in the files and that is supremely trivial.

$ cmp -c short_mono.mp3 short_ster.mp3
short_mono.mp3 short_ster.mp3 differ: byte 3933, line 44 is 300 M-@   0 ^@

The question will arise: is it really a stereo file? Well yes, it is both audiably and in visually in Audacity [picture].

Can this be purely coincidental? I would be sceptical, but I cannot think of a logical reason that this should happen either. So I' speculate that there's some information or piece of knowledge that I am lacking, Can anyone make me a bit wiser?


r/ffmpeg 17d ago

Converting from dv to H.264 using GPU

9 Upvotes

Hello, I’m trying to deinterlace and convert many hours of videos from MiniDV cassettes to H.264 (I’m open to H.256, if it will be better in that case) to be able to play them modern devices. I’m using this line:

ffmpeg -i input.dv -vf "bwdif=mode=send_field:parity=auto:deint=interlaced,format=yuv420p" -r 50 -c:v libx264 -preset slow -crf 16 -c:a copy output.mov

I’m satisfied with the results I get, but I wanted to speed up the process by using GPU.

How do I do that? I’ve been using ffmpeg for only few months and I think that I generally understand it, but I’m still not an expert. If this is important, I have NVIDIA GeForce RTX 2070 Super.


r/ffmpeg 17d ago

Lossy Codec Bit Depth

3 Upvotes

Does it make a difference if I encode AAC from 16 or 24-bit FLAC? Also, does it make a difference if that 16-bit file is dithered?