Intermediate Files for Editing

Shotcut is not a ffmpeg command line frontend (except for Properties > Convert and More Information).

I’m thinking I need to disable GPU processing but I am not saving the project as an MLT file. I am loading the bmp directly into shotcut and exporting it. I will see what’s the deal with an MLT file.

Just checked. Settings -> GPU Effects is unchecked.

I did some testing and found RGB output (mlt_image_format=rgb24 and PNG or HuffYUV with pix_fmt=rgb24) from Shotcut is good but anything using YUV is darkened. I will work on a fix.

Testing Details

To assess the color handling, first start with RGB handling input-through-output along with a test process. I plan to use ffmpeg to convert one frame of something to PNG, and open it in paint.exe to use its color picker and edit colors tools to get the resulting RGB values. (You can use another tool such as Gimp, but I did not want to wait for it to load). I am using RGB (16,180,16) = #10B410 (#FF10B410) in Shotcut’s color generator). I am using Shotcut 18.10.08 and ffmpeg 4.0.x that comes with it.

RGB24 -> RGB24 (full range)

Shotcut: Using the color generator and the PNG export preset with mlt_image_format=rgb24, I get
(16,180,16).

Using ffmpeg -f lavfi -i color=#10B410 -t 0.04 -pix_fmt rgb24 /i/testing/r16g180b16-ffmpeg-rgb24.png I get (15,177,14) !! That’s not good! Let’s try using Shotcut’s PNG as input:

Using ffmpeg -i '/i/testing/r16g180b16-shotcut-rgb24-00001.png' -pix_fmt rgb24 /i/testing/r16g180b16-ffmpeg-rgb24.png I get (16,180,16).

OK, now we have a combination of things that we can trust.

x264 yuv444p

Using ffmpeg

ffmpeg -i '/i/testing/r16g180b16-shotcut-rgb24-00001.png' -pix_fmt yuv444p /i/testing/r16g180b16-ffmpeg-yuv444p.mp4
ffmpeg -i '/i/testing/r16g180b16-ffmpeg-yuv444p.mp4' -pix_fmt rgb24 /i/testing/r16g180b16-ffmpeg-yuv444p.png

I get (16,179,15).

Shotcut: Using the color generator and the export defaults with other:

mlt_image_format=rgb24
pix_fmt=yuv444p

and ffmpeg -i '/i/testing/r16g180b16-shotcut-yuv444p.mp4' -pix_fmt rgb24 /i/testing/r16g180b16-shotcut-yuv444p.png
I get (4,154,10). That is a problem.

x264 yuvj444p (full range)

ffmpeg -i '/i/testing/r16g180b16-shotcut-rgb24-00001.png' -pix_fmt yuvj444p /i/testing/r16g180b16-ffmpeg-yuvj444p.mp4
ffmpeg -i '/i/testing/r16g180b16-ffmpeg-yuvj444p.mp4' -pix_fmt rgb24 /i/testing/r16g180b16-ffmpeg-yuvj444p.png

I get (15,180,16).

Shotcut: Using the color generator and the export defaults with other:

mlt_image_format=rgb24
pix_fmt=yuvj444p

and ffmpeg -i '/i/testing/r16g180b16-shotcut-yuv444p.mp4' -pix_fmt rgb24 /i/testing/r16g180b16-shotcut-yuv444p.png
I get (3,154,12). That is a problem.

x264 yuv422p

ffmpeg -i '/i/testing/r16g180b16-shotcut-rgb24-00001.png' -pix_fmt yuv422p /i/testing/r16g180b16-ffmpeg-yuv422p.mp4
ffmpeg -i '/i/testing/r16g180b16-ffmpeg-yuv422p.mp4' -pix_fmt rgb24 /i/testing/r16g180b16-ffmpeg-yuv422p.png

I get (15,177,14).

Shotcut: Using the color generator and the export defaults with other:

pix_fmt=yuv422p

and ffmpeg -i '/i/testing/r16g180b16-shotcut-yuv422p.mp4' -pix_fmt rgb24 /i/testing/r16g180b16-shotcut-yuv422p.png
I get (1,153,7). That is a problem.

HuffYUV

I get similar poor results from Shotcut using huffyuv yuv422p but not with

mlt_image_format=rgb24
pix_fmt=rgb24

Why are you testing with PNG and not BMP?

Arbitrary choice.
I found a flaw with my test procedure. The Shotcut/MLT color generator tries to generate in YUV if the image was requested in that image format, not RGB. It uses some suspicious coefficients for that. If I use the PNG source that I used for ffmpeg in Shotcut, then I get (13,178,13) for x264 yuv422p, which is much closer to expected and ffmpeg’s result.

A possible fix to be included in the official v18.11 release? :wink:

Here are the results I get for different codecs using ffmpeg directly, rather than through Shotcut:

Original: 16, 180, 16

ffv1: 18, 149, 25

huffyuv: 18, 149, 25

x.264:16, 179, 16 (yuv420p, crf 0)

x.265:16, 179, 16 (yuv420p, crf 0)

It is my casual observation that a color value +/- 3 is acceptable.

How the colors were chosen:

16 is familiar to anyone who works with BT.709

0.75 * (235 - 16) + 16 =180

This is the SMPTE RP 219 standard for 75% color bars. It is the standard in professional work.

Can you share your ffmpeg command line and ffmpeg version? I tried the same thing and got perfect results for FFV1 and HuffYUV. ffmpeg 4.0.2

Is this from within Shotcut or extrinsically?

My tests were calling ffmpeg directly. Your message prior to mine (the SMPTE color bars reference) sounded like you were using ffmpeg as well. I was wondering how we both used ffmpeg and got different results for FFV1 and HuffYUV.

Here is the command line I used:

ffmpeg -y -i raster.bmp -c:v huffyuv raster.mkv

What is your command line?

How are you testing the color accuracy?

Full details at Intermediate Files for Editing

SMPlayer gives me perfect colors, but my self-coded player, which works fine on x.264 and x.265, does not. So I have to look into my player code. Also, I can use the combination of an eyedropper program and SMPlayer or MPC-BE media player. My ffmpeg is fairly recent from Zeranoe.

Now to retry the Shotcut color tests using SMPlayer and eyedropper.

VLC did not even play back the ffv1 file.

Now I’m getting colors +/- 2 using SMPlayer and eyedropper using Shotcut to export both ffv1 and huffyuv. So there is a problem in my own code.

OK, here’s the deal:

My “naked” ffv1 and huffyuv code was giving me RGB24 color.

Shotcut’s ffv1 and huffyuv give me YUV 4:2:2. I can change this to 4:2:0 or 4:4:4. Shotcut’s “lossless” H.264 gives YUV 4:2:0.

I have to use a different program (I have written two) depending on whether it’s YUV or RGB. When I choose the RGB program for FFV1 or Huffyuv I get perfect colors. Truly perfect meaning +/- 0, from my “naked” ffmpeg script which outputs RGB. It is truly lossless and there are no color errors.

A request for the Shotcut developers: Please make the “lossless” H.264, ffv1 and huffyuv output RGB24 instead of YUV 4:2:0 and 4:2:2. By their nature these subsampled formats throw away chroma samples so in reality they are lossy, not truly lossless.

If a user needs a more compact file he can choose one of the other flavors of lossy H.264 or H.265.

Thank you.

A question because I don’t know the answer…

Since virtually all consumer cameras create video in YUV (by default at least), and even pro cameras end up in YUV if converted to ProRes from raw, would setting the default lossless export formats to RGB actually create loss rather than avoid it since a colorspace conversion would be needed to get into RGB? The only RGB sources I would expect most people to encounter would be computer-generated logos and slides, and 3D animations. The other 98% of sources (which includes H.264 screen recordings of video games) would be YUV from the start. So would exporting as YUV avoid a conversion and be more lossless than exporting as RGB? The part I don’t know is if re-encoding YUV-to-YUV is truly lossless, or just as bad as going to RGB.

I am all in favor of having additional presets for RGB. I don’t know what to think about making RGB the default until learning if YUV-to-YUV is lossless. I would assume it is, but I’ve been wrong before.

To my knowledge, ProRes and H.264 don’t support RGB via ffmpeg, so that complicates things too.

You’re making assumptions about a user’s workflow.

My point is that the “lossless” formats are not truly lossless if they downsample the original’s pixel format: RGB to YUV or YUV 4:4:4 to 4:2:2.

Along comes a user with 4:4:4 material and he uses Huffyuv export. Shotcut downsamples it to 4:2:2 so it’s not really lossless because chroma information has been discarded, i.e. lossy.

In Shotcut’s FFV1 export under the “Other” tab you can specify the pixel format and specify 4:2:0, 4:2:2 or even 4:4:4, and it actually works in YUV, but you cannot specify rgb24.because it will not export to that. If this facility allowed you to choose any pixel format and have it export to that, I think that would be useful, letting the user override the default.

Why don’t you take some 4:2:0 material, check the colors, export it as Huffyuv (which will come out as 4:2:2) , check the colors again and see if they change?

I took my bmp test file and exported it as “lossless” H.264 using the default settings. It came out as 4:2:0. The colors were 28-171-26.

I then re-imported that file and re-exported it, again as “lossless” H.264. The colors came out as 4:2:0, 28-171-26, exactly the same. So there was no color change because the subsampling and color space did not change. I got the same results when I exported as 4:4:4 by specifying pix_fmt=yuv444p. I then exported to FFV1 and 4:4:4: same thing. So you get errors when going from RGB to YUV but we knew that.

So if you’re starting with YUV 4:2:0 you can export it to ffv1 OR to “lossless” H.264 as YUV 4:2:0, 4:2:2 or 4:4:4 without any color change. The pixel format changes but we are staying in YUV. Apparently whenever you have subsampling, Shotcut goes to YUV, which is fine. You cannot do this with Huffyuv, however…

Please, please, developers, please add this capability to Huffyuv.

Does this answer your questions, Austin?

Cool test, I learned something. That’s why I ask questions. :slight_smile:

In that case, the feature you want may already exist. If you want Shotcut to operate in rgb24 instead of YUV, I think you can add these lines to Export > Other:

mlt_image_format=rgb24
pix_fmt=rgb24

Then in theory (I haven’t tested yet), exporting this to HuffYUV would get you a completely RGB pipeline. Is that what you were wanting?

ffmpeg -h encoder=huffyuv doesn’t list yuv444p as a supported pixel format, so I think that prevents Shotcut from exporting 4:4:4 HuffYUV. This is one of many reasons I switched to Ut Video, to get the extra pixel format support.

Same with FFV1… ffmpeg -h encoder=ffv1 doesn’t list rgb24 as a pixel format. However, it has rgb48le, rgba64le, and a slew of bgrpXle bit depths or the more simple bgr0 formats to work with. Specifying any of those would get you the RGB lossless you seek, albeit with massively more headroom than you may ever need. These archival guys don’t mess around haha.

I’m not so worried about RGB as the bulk of input material is likely YUV.

I would like to see 4:2:0, 4:2:2 and 4:4:4 supported for HuffYUV if possible. Does ffmpeg support this?