So after hours of searching for a solution, correct me if I am wrong, but it seems that it is just not possible to encode an RGB image sequence (with a baked in gamma curve, not linear) to h.264 using either ffmpeg libx264 or x264 without incurring a color shift. If someone knows of a way, I am all ears because the workaround is a massive pain. And I am not interested in using Avisynth.
+ Reply to Thread
Results 1 to 30 of 41
-
-
You can encode in RGB, which will almost ensure no problems occur; but it's not very efficient (compression wise) compared to YUV, and less compatibility with some devices, some software
for x264,
Code:--input-csp rgb --output-csp rgb
Code:-c:v libx264rgb
-
Code:
-color_primaries <int> ED.V.... color primaries (from 1 to 10) (default unspecified) bt709 ED.V.... BT.709 unspecified ED.V.... Unspecified bt470m ED.V.... BT.470 M bt470bg ED.V.... BT.470 BG smpte170m ED.V.... SMPTE 170 M smpte240m ED.V.... SMPTE 240 M film ED.V.... Film bt2020 ED.V.... BT.2020 smpte428_1 ED.V.... SMPTE ST 428-1 -color_trc <int> ED.V.... color transfer characteristics (from 1 to 18) (default unspecified) bt709 ED.V.... BT.709 unspecified ED.V.... Unspecified gamma22 ED.V.... BT.470 M gamma28 ED.V.... BT.470 BG smpte170m ED.V.... SMPTE 170 M smpte240m ED.V.... SMPTE 240 M linear ED.V.... Linear log ED.V.... Log log_sqrt ED.V.... Log square root iec61966_2_4 ED.V.... IEC 61966-2-4 bt1361 ED.V.... BT.1361 iec61966_2_1 ED.V.... IEC 61966-2-1 bt2020_10bit ED.V.... BT.2020 - 10 bit bt2020_12bit ED.V.... BT.2020 - 12 bit smpte2084 ED.V.... SMPTE ST 2084 smpte428_1 ED.V.... SMPTE ST 428-1 -colorspace <int> ED.V.... color space (from 0 to 10) (default unspecified) rgb ED.V.... RGB bt709 ED.V.... BT.709 unspecified ED.V.... Unspecified fcc ED.V.... FCC bt470bg ED.V.... BT.470 BG smpte170m ED.V.... SMPTE 170 M smpte240m ED.V.... SMPTE 240 M ycocg ED.V.... YCOCG bt2020_ncl ED.V.... BT.2020 NCL bt2020_cl ED.V.... BT.2020 CL -color_range <int> ED.V.... color range (from 0 to 2) (default unspecified) unspecified ED.V.... Unspecified mpeg ED.V.... MPEG (219*2^(n-8)) jpeg ED.V.... JPEG (2^n-1) -chroma_sample_location <int> ED.V.... chroma sample location (from 0 to 6) (default unspecified) unspecified ED.V.... Unspecified left ED.V.... Left center ED.V.... Center topleft ED.V.... Top-left top ED.V.... Top bottomleft ED.V.... Bottom-left bottom ED.V.... Bottom
Code:colormatrix AVOptions: src <int> ..FV.... set source color matrix (from -1 to 4) (default -1) bt709 ..FV.... set BT.709 colorspace fcc ..FV.... set FCC colorspace bt601 ..FV.... set BT.601 colorspace bt470 ..FV.... set BT.470 colorspace bt470bg ..FV.... set BT.470 colorspace smpte170m ..FV.... set SMTPE-170M colorspace smpte240m ..FV.... set SMPTE-240M colorspace bt2020 ..FV.... set BT.2020 colorspace dst <int> ..FV.... set destination color matrix (from -1 to 4) (default -1) bt709 ..FV.... set BT.709 colorspace fcc ..FV.... set FCC colorspace bt601 ..FV.... set BT.601 colorspace bt470 ..FV.... set BT.470 colorspace bt470bg ..FV.... set BT.470 colorspace smpte170m ..FV.... set SMTPE-170M colorspace smpte240m ..FV.... set SMPTE-240M colorspace bt2020 ..FV.... set BT.2020 colorspace colorspace AVOptions: all <int> ..FV.... Set all color properties together (from 0 to 8) (default 0) bt470m ..FV.... bt470bg ..FV.... bt601-6-525 ..FV.... bt601-6-625 ..FV.... bt709 ..FV.... smpte170m ..FV.... smpte240m ..FV.... bt2020 ..FV.... space <int> ..FV.... Output colorspace (from 0 to 10) (default 2) bt709 ..FV.... fcc ..FV.... bt470bg ..FV.... smpte170m ..FV.... smpte240m ..FV.... bt2020ncl ..FV.... range <int> ..FV.... Output color range (from 0 to 2) (default 0) mpeg ..FV.... jpeg ..FV.... primaries <int> ..FV.... Output color primaries (from 0 to 10) (default 2) bt709 ..FV.... bt470m ..FV.... bt470bg ..FV.... smpte170m ..FV.... smpte240m ..FV.... bt2020 ..FV.... trc <int> ..FV.... Output transfer characteristics (from 0 to 18) (default 2) bt709 ..FV.... gamma22 ..FV.... gamma28 ..FV.... smpte170m ..FV.... smpte240m ..FV.... bt2020-10 ..FV.... bt2020-12 ..FV.... format <int> ..FV.... Output pixel format (from -1 to 338) (default -1) yuv420p ..FV.... yuv420p10 ..FV.... yuv420p12 ..FV.... yuv422p ..FV.... yuv422p10 ..FV.... yuv422p12 ..FV.... yuv444p ..FV.... yuv444p10 ..FV.... yuv444p12 ..FV.... fast <boolean> ..FV.... Ignore primary chromaticity and gamma correction (default false) dither <int> ..FV.... Dithering mode (from 0 to 1) (default none) none ..FV.... fsb ..FV.... wpadapt <int> ..FV.... Whitepoint adaptation method (from 0 to 2) (default bradford) bradford ..FV.... vonkries ..FV.... identity ..FV....
-
What is the current "favorite" method for RGB => 4:2:0 YUV using 709 , pandy ?
The old way for RGB => YUV using 709 was -pix_fmt yuv420p and -vf colormatrix=bt601:bt709 , this was also used in ffmbc but the quality was always lower than doing in avisynth .
Another way was -vf scale using -in_color_matrix and -out_color_matrix -in_range and -out_range, but again , lower quality
The other ways were "broken" or had problems. I wonder if -colorspace 1 is "fixed" now ? -
I posted some comparisons , sneaker, either here, or doom9, or ffmbc google board about 2-3 years ago. There was a 3rd way in ffmbc to do it , but it was still worse. Keep in mind that you can specify the algorithm too (bicubic, lanczos, etc.. by using the ffmpeg sws_flags, for an "apples to apples" comparison, that might have been the partial difference because the algorithms were slightly different there was no spline36, ffmpeg uses "soft spline" which is closer to spline16, but not quite the same as avisynth's spline16) . The scale filter might have been patched since then, I haven't tested it recently . I recall vaguely kolak mentioning using -colorspace in a more recent thread which was 100% definitely broken back then, but I haven't tested it recently either
-
Since rgb is not listed as a potential source then I guess something like -vf colormatrix=rgb:bt709 is not possible? So how does one tell ffmpeg how to convert an RGB image sequence to bt709 without a color shift?
-
-
I didn't look at your bars yet, but are you talking about rounding error shifts (ie minor), or something larger, noticable with naked eye ?
Because both those old methods work (still) . And because of the 8bit precision, you're not going to identical colors, there is going to be a tiny shift unless you use RGB -
No, sadly, it is not a minor difference due to rounding etc. It is very noticeable with the naked eye. If it wasn't, I probably wouldn't care since this is for final delivery as opposed to round tripping for compositing where even a subtle difference is not tolerable.
EDIT: FWIW, I can transcode the image sequence to ProRes using Nuke and bypass this color shift in ffmpeg/x264, but inserting a ProRes transcode into the workflow is a hassle. -
I tested a recent ffmpeg just an hour ago on other colorbars and the old method 1 and 2 work fine. I also set the flags for 709, but that shouldn't affect the actual conversion. How are you viewing / determining the final result . I like method #2 better (vf scale) because you have other options like interlaced scaling for the chroma etc.. all within the single filter
-
I am using the zeronoe's most recent x64 ffmpeg build. As for viewing, I see the difference on my GUI, color managed monitor, and my scopes and recall, if I transcode the sequence to ProRes in Nuke then encode to h.264 with ffmpeg/x264, there is no color shift. Can you post exactly which commands you use for method 1 and 2, just to make sure I am not missing something? Thanks.
Also, I tried a tiff sequence as well, and the exact same shift, so I don't think the problem is due to exr. -
Yes, I see the larger shift with your exr sequence. ffmpeg has a problem that exr sequence (but not just that one apparently, different variants, no compression, RLE , zip1 etc...) .
e.g. source 8bit RGB PNG (just to be complete, with flags, sar, but that won't affect the actual conversion)
Code:ffmpeg -r 24 -i testchart720.png -pix_fmt yuv420p -vf scale=out_color_matrix=bt709,setsar=sar=1/1 -frames 1 -c:v libx264 -crf 18 -x264opts colorprim=bt709:transfer=bt709:colormatrix=bt709:force-cfr -an vfscale.mp4
There are your typical rounding errors , 1 or 2 of 256 values off, but not the large shift I'm seeing when ffmpeg touches EXR. Try converting the EXR with ffmpeg just to 16 bit RGB like a png or tiff (forget YUV for a minute) and you will still see a large shift even then (e.g. the grey bars are way off) -
I think it's not handling the linear conversion very well for exr. You can bake in the ~2.2 gamma curve with -apply_trc gamma22 and it will be a lot closer, but still off a few here and there, especially at lower values. Conversions are more accurate with linear workflow like nuke or ae in 32bit linear mode
Or use something else other than ffmpeg or export something else other than exr
eg.
Code:ffmpeg -r 24 -apply_trc gamma22 -i colorbars01.exr -pix_fmt yuv420p -vf scale=out_color_matrix=bt709,setsar=sar=1/1 -frames 1 -c:v libx264 -crf 18 -x264opts colorprim=bt709:transfer=bt709:colormatrix=bt709:force-cfr -an gamma2.2.mp4
Code:EXR AVOptions: -layer <string> .D.V.... Set the decoding layer (default "") -gamma <float> .D.V.... Set the float gamma value when decoding (from 0.001 to FLT_MAX) (default 1) -apply_trc <int> .D.V.... color transfer characteristics to apply to EXR linear input (from 1 to 18) (default gamma) bt709 .D.V.... BT.709 gamma .D.V.... gamma gamma22 .D.V.... BT.470 M gamma28 .D.V.... BT.470 BG smpte170m .D.V.... SMPTE 170 M smpte240m .D.V.... SMPTE 240 M linear .D.V.... Linear log .D.V.... Log log_sqrt .D.V.... Log square root iec61966_2_4 .D.V.... IEC 61966-2-4 bt1361 .D.V.... BT.1361 iec61966_2_1 .D.V.... IEC 61966-2-1 bt2020_10bit .D.V.... BT.2020 - 10 bit bt2020_12bit .D.V.... BT.2020 - 12 bit smpte2084 .D.V.... SMPTE ST 2084 smpte428_1 .D.V.... SMPTE ST 428-1
-
Thanks as always, pdr. I believe I found the solution.
If I export linear bars, instead of sRGB, and set the -apply_trc to linear, then the resulting mp4 has no colorshift and remains linear. Therefore, the next step is figuring out which LUT to choose. I played around with a few, gamma22, gamma28, bt709, but no luck. Then I checked the wiki:
https://en.wikipedia.org/wiki/SRGB
which states that sRGB is defined by IEC 61966-2-1:1999. So, I decided to try the iec61966_2_1 option, and it looks spot on! Can you confirm if you see the same results on your end?
Also, maybe it is just me, but it is annoying that they call it that instead of just sRGB. It is like trying to decipher the Rosetta stone.Last edited by SameSelf; 24th Oct 2016 at 19:01.
-
Yes, that's a closer match. Nice find. Probably the closest you're going to get doing it this way
-
Well, I was sort of forced into the image format world. Round tripping small segments for compositing requires absolute losslessness to avoid obvious artifacts in the playback. And linear half float openEXR is so much easier to use than any other format. I transitioned a while ago, but I didn't realize the final encode to YUV was incurring a color shift. Needless to say I was shocked and somewhat despondent. There is nothing worse than the feeling you get after spending hours grading footage only to find ffmpeg/x264 just messed it all up. I re-encoded my most recent video last night after stumbling on the solution—just to be sure. It was perfect, no issues at all. I have some other ideas that I came across in my research of this problem. I will probably do some more tests and post back here with my results.
-
I'm getting some errors on a chart. I'll don't have time right now to debug right now, it might have been something on my part but I'll report back tonight
-
Actually, I did test the belle nuit chart last night and noticed quite a few differences/errors as well. However, that chart is made to really stress test encoder artifacts due to subsampling, superwhites, etc. So, I wasn't clear if the differences were due to things like 420 vs 422, clamping, or otherwise. Honestly, there is just too much going on in that chart to be real useful for what I was doing. But, there might be some more gotchas that I didn't catch which is why I want to do some more tests.
I have one idea but haven't gotten a chance to try yet, so if you have some time you might give it a shot. What if I export with sRGB baked in and set -apply-trc to linear? Since we know that setting -apply-trc to linear leaves linear sequences in tact, I am wondering if it will leave sequences with baked in LUTs alone as well. Ideally, I think this would be a better option as I trust setting the LUT in my NLEs a lot more than leaving it to ffmpeg. -
No nothing like the expected tiny rounding errors; it's a critical error , a dark blue gradient turns bright green, but only in dark areas. But so far it only affects AE writing exr half float (piz, zip so far) . Other programs can write those exr variants fine, ffmpeg ok . Full float seems fine too across the board . I'm still looking into in, more later . Not a decoding error with other programs, because other programs "see" the "bad" exr variants ok (no green error), and AE "sees" it's own exr export fine too . So it seems like some compatibility issue with half float exr's written by AE (at least AE CC2015 with piz and zip, haven't tested them all yet) and ffmpeg so far
And issue #2 is you can't seem to control the dither algo (but you can with other situations in ffmpeg, so not sure what's up with that) . Dither pattern might not be ideal for all situations. For example if you were using bars, or solid colors, or maybe a clean graphics title sequence, it might not look ideal. You're supposed to be able to change the dither pattern with sws flags but it's not working here (something might be broken in my ffmpeg build, but it works for other operations, other scenarios) . -sws_dither none or 0 is supposed to turn it off completely (so you get clean solid colors, instead of fluctuations on a supposedly "single" color)
Code:-sws_dither <int> E..V.... set dithering algorithm (from 0 to 6) (default auto) auto E..V.... leave choice to sws bayer E..V.... bayer dither ed E..V.... error diffusion a_dither E..V.... arithmetic addition dither x_dither E..V.... arithmetic xor dither
The half float exr issue might be related to the AE version (there are still various bugs in the 2015.1/2/3 versions), can you test it in CS6 ? I don't have it handy. Just drop that belle nuit chart in a 32bpc chart and export a half float exr (whatever compression, I've been using zip and piz which are the most common) , and feed it to ffmpeg .
This was the result of the 1080 half, piz test, run through ffmpeg with that same command but with CRF1 to minimize compression issues .(It also affects 720, so probably not resolution related), you can see the green error , and if you look closely e.g. the left bar has a "grid" pattern, or run a color picker across it, the dither issues with "solid" colors
Last edited by poisondeathray; 25th Oct 2016 at 13:11.
-
Wow! I did not see that bright green error in the dark blue in my test. But I only tested it in Resolve. I will definitely try it out in AE CS6 tonight to see if it shows up for me as well. I will probably test nuke too, just to be certain. And that is interesting that turning off dithering does not seem to work. I will test that too on my end.
-
Sorry for late reply - to be honest i found ffmpeg as uncontrollable on some video conversion aspects - it looks like additional conversions are invoked automatically without telling user anything... Seem that ffmpeg developers don't care too much if common actions works for them...
I provided options as they are relatively new to many ffmpeg users. -
I did some very quick tests because I am pressed for time, but very, very strange. I imported the belle nuit chart into AE CS6, dropped it into a FHD 32bpc comp and exported as half float exr with piz compression and fed it to ffmpeg, and I got the same green bar! Just to see what would happen, I brought the AE export into Resolve, exported from Resolve as exr piz half float again, and fed that to ffmpeg, and the mp4 was fine. So clearly something is up with AE half float exr, and the problem seems to exist in both CS6 and CC2015.
Also, my suspicion was correct. If I export from Resolve with an sRGB LUT baked in and set -apply_trc to linear, then the resulting mp4 is fine, or at least nearly identical to exporting as linear and setting -apply-trc to iec61966_2_4.
I am running out of time presently, but I wonder if exporting out of AE with sRGB baked into the exr might help with the green cast problem. -
Alright, another quick test. I turned off the convert to linear light option in AE and after exporting as half float exr piz, the ffmpeg encode did not have the green bar on the blue ramp. So, that's some good news in that there is a pathway out of AE if you are going straight to ffmpeg vs another program while at the same time, if you are going to another program, it looks like the issue is not preserved at least through Resolve. Need to test other programs like nuke to see if they behave similarly.
Also, it seems there is a bug in -swscale per this thread:
http://ffmpeg-users.933282.n4.nabble.com/RGB-YUV-color-shift-td4654294.html
related to the chroma subsampling that causes the green tint you mentioned and adding -sws_flags lanczos+accurate_rnd reportedly fixes the problem. But my quick testing didn't reveal much, if any, difference.
Lastly, I haven't had a chance to play around much with the dither options yet. I tried a quick test, and similar to your results, setting it to none doesn't seem to do anything.Last edited by SameSelf; 25th Oct 2016 at 22:13.
-
That linked thread is a separate, older issue with 709 vs 601 from a few years ago, it's not related to the green bar AE half float piz exr issue.
This is not a RGB/YUV issue, because if you convert to RGB (either 8 or 16bit) with ffmpeg, bug is still there.
I already mentioned, programs like nuke, resolve etc.. aren't affected. ffmpeg handles the same half float/piz/exr exported from them without issues. Also the AE "buggy" exr is imported fine into itself and those other programs. So I wouldn't call it an AE bug, rather an ffmpeg bug. Its limited to that AE variant interacting with ffmpeg libraries. (It just happens that that variant is probably the 2nd most common EXR variant behind full float, so I'm surprised someone didn't stumble on this earlier). Even the djv_view which shares the same libraries and is probably the "standard" for open source image viewers for EXR and similar formats has the same bug. So it's definitely the ffmpeg/libav handling issue. But it makes you wonder what other bugs are lurking. -
I was thinking that the problem was due to ffmpeg as well when I saw that the AE exr was handled properly by resolve. At the same time, I find it quite curious that if you set the linear conversion to off in the AE render settings them the problem goes away. So the problem seems to be specifically how ffmpeg handles linear images. And there must be something in the AE version throwing it off. So I agree that it is not an RGB to YUV problem.
-
Well, this stinks. I thought from my quick testing that by turning off the linear light option I would be fine. But for my latest project, after exporting from AE and encoding, ffmpeg somehow mangled my footage. It wasn't a color shift but some really bizarre artifacts that looked like neon lights in the black areas. I was under a time crunch, so I had no choice but to bring the exr into Resolve and re-export to get whatever was causing the problem fixed. I will try to do some more testing when I get some time. exr is ideal for finishing and compositing, but lots of gotchas when it comes to ffmpeg.
Similar Threads
-
Converting Between 10-bit RGB and YUV and Back
By chris319 in forum Video ConversionReplies: 22Last Post: 8th Jul 2016, 23:53 -
YUV/ RGB problem in Avisynth
By spiritt in forum Newbie / General discussionsReplies: 9Last Post: 6th Sep 2015, 04:31 -
is this YUV or RGB?
By marcorocchini in forum Newbie / General discussionsReplies: 2Last Post: 20th Apr 2014, 10:21 -
MENCODER: how to convert from YUV to RGB?
By marcorocchini in forum Newbie / General discussionsReplies: 1Last Post: 19th Dec 2013, 13:24 -
YUV 4:2:0 to RGB
By toshyuki in forum ProgrammingReplies: 15Last Post: 8th Oct 2012, 12:12