I'm trying to process the video I recorded from my capture card and that involves storing the videoframes as PNG images at some point. The problem is, FFmpeg shifts the chroma planes ~2px to the right when converting from YUV to RGB. This adds to the already existing shift that my capture card introduces and becomes quite noticeable. I tried the sws_flags solution but it only fixes the blockiness. I also tried to horizontally flip the video before conversion in hopes that it would reverse the shift direction, to no effect.
So I need to compensate for both and shift chroma to the left. I've seen examples of overlay filter_complex usage shifting the whole video, as well as the chroma planes extraction via lut_yuv, but I can't figure out how to shift only the chroma plane. There doesn't seem to be a 'chroma' mode in the blend filter either, which would have allowed me to replace chroma with its modified version.
Conversion log:
FixChromaBleeding is an old standby that starts by reducing chroma oversaturation, which is a major cause of bleeding and 'blooming' effects. FixChromaBleeding also does some internal resizing to help contain bleed. ChromaShift(c=2,L=-2) shifts chroma displacement 2 pixels to the right and 2 pixels upward.
Source image:
You can see there's already a 2px shift just from the YUY2 capture format
FFMpeg conversion:
Now it's twice as big
1 Answer
Basic method to adjust or shift chroma is to use the geq
filter.
The chroma is upscaled to full size, then the individual planes are extracted. In the geq
filters, applied to the U and V extracted planes, the value of each pixel is taken from the pixel to its right. This will lose the original values of the leftmost column of pixels. Finally, the original luma and processed chroma planes are merged. Using some trial and error, you should be able to get the offsets right.