You can do it with 8bit RGB => YUV conversion. That's the whole point of rp219. They give exact YUV values for 10 and 12 bit too
And it's definitely possible when adding youtube compression on top with ffmpeg using 8bit, I just checked.
Not a big deal; but if you can have perfect specs, why not use perfect specs ?
You send RGB 5-246, but the BMP written by ffmpeg is 0-255 ?
Are you sure you're not doing other stuff before ffmpeg step ?
Or maybe there are issues with the internal check ? or some other assumptions need rechecking?
or why don't you just clip in FFmpeg ? lutrgb ?
Try StreamFab Downloader and download from Netflix, Amazon, Youtube! Or Try DVDFab and copy Blu-rays! or rip iTunes movies!
+ Reply to Thread
Results 61 to 90 of 328
Thread
-
-
You can do it with 8bit RGB => YUV conversion. That's the whole point of rp219.
Get YouTube to use your encoder, too.Last edited by chris319; 14th Feb 2020 at 21:51.
-
You don't need a patch. It's already accurate
I used ffmpeg libx264, there is no floating point error . I doubt x265 has one either
You just encode the bmp or png normally using 191 bars. 75% for 0-255 RGB. Use limited range 709 conversion. (ie. a "normal" everyday conversion)
something like this
Code:ffmpeg -r 24 -loop 1 -i 191bars.png -vf scale=out_color_matrix=bt709,format=yuv420p -c:v libx264 -crf 16 -t 10 -an test191.mp4
Anyways, youtube didn't kill it either; YUV values match rp219 exactly when you download the video
Accuracy is the supposedly the point of rp219 and color bars in general. If you can get 100% perfect just using ffmpeg normally using 8bit, then why not ?
I already mentioned above - but if you used 180,16,16 , 75% for 16-235, values are slightly off using existing full range 709 conversion routines as-is. You need that levels workaround to get it matching. -
if you used 180,16,16 , 75% for 16-235, values are slightly off using existing full range 709 conversion routines as-is. You need that levels workaround to get it matching.
The actual colors don't make a difference anyway, as long as the color out matches the colors in the original bmp. You could use 64-180-200 but you want to see that color on the output.Last edited by chris319; 15th Feb 2020 at 12:48.
-
I used your code and got the same +/- 3 floating-point errors. Tried it in several players including (MPC-BE). All of the colors are perfect in "test_pattern_709.bmp".
Code:ffmpeg -y -r 24 -loop 1 -i "test_pattern_709.bmp" -vf scale=out_color_matrix=bt709,format=yuv420p -c:v libx264 -crf 16 -t 10 -an test191.mp4
-
Then why are all the colors slightly off? It's unexpected
I thought it might be YT, but I tested yesterday and it survived YT intact.
You can use studio range RGB if you really wanted to, it's just rare to work with and most computer programs and displays aren't setup to deal with it. That levels workaround can work in 8bit too (at least for the rp219 bar values given), and the values end up matching too, The earlier example used normalized non linear 0-1.0 range, but it's not required
For RGB=>YUV rp219 bars e.g. avisynth
Code:#studio range RGB source (RGB 16-235) Levels(16,1,235,0,255) ConvertToYV12(matrix="rec709") #4:2:0
-
We're talking about actual YUV values. ie. The values given in rp219 . Those are the specs you want to match
Not your YUV converted back to RGB values. If you wanted the original RGB values for the roundtrip, then yes you need 10bit YUV . All the original 8bit RGB colors fit in 8bit YUV color model. But you need 10bit to overcome the lossy rounding for the round trip back to RGB -
We're talking about actual YUV values. ie. The values given in rp219 . Those are the specs you want to match
Not your YUV converted back to RGB values.
Ultimately the YUV is converted to RGB and sent to the graphics card/monitor and that's what the viewer sees. The small amount of fp error after conversion to RGB doesn't bother me. We're off the 180-16-16 now so get over that. I'll let you chase that. I need to get back to the original subject of this thread which involves ffmpeg. -
You were given two choices that actually work; I looked at a few others, but most actually read a RGB converted version then convert back YUV, not the YUV values directly
If you were to pick one I would say vapoursynth and vsedit, because it's cross platform, supports many pixel formats and bit depths. 10bit is getting more and more common now, even for consumer formats.
Ultimately the YUV is converted to RGB and sent to the graphics card/monitor and that's what the viewer sees. The small amount of fp error after conversion to RGB doesn't bother me.
And if you did want perfect color accuracy for actual program submission, just use something like prores or dnxhd 10bit variants . If the distribution format was 10bit or had 10bit options (e.g. UHDBD, many broadcaster in europe, netflix etc...) , then use 12bit prores or dnxhd variants. +2 bits is usually enough
I need to get back to the original subject of this thread which involves ffmpeg.
Did you do something differently to make that 1st youtube video ? Can you repeat the process with that commandline above to get correct rp219 YUV values ? -
And if you did want perfect color accuracy for actual program submission, just use something like prores or dnxhd 10bit variants . If the distribution format was 10bit or had 10bit options (e.g. UHDBD, many broadcaster in europe, netflix etc...) , then use 12bit prores or dnxhd variants. +2 bits is usually enough
I am performing the 5 - 246 limiting in the RGB domain and it works fine. I think the trouble is when I save the RGB data as YUV. The video is not playable when written as RGB24.
This is why legalizing video is such a daunting problem. Some people swear by hardware legalizers and say that's the only way to go. -
But you said sending 5-246, and saving it as a BMP was incorrect already. No YUV step. That suggests a problem upstream with RGB.
Uncompressed RGB24 (or BGR24) in a container (e.g. AVI) is playable by MPCHC, MPV, etc.. Raw RGB24 can be playable with ffplay or vsedit, but you need to enter the parameters such as -pix_fmt , -r, -s . Raw RGB has no header info, so you have to fill that in that info so the player knows what to do with the raw sampels
This is why legalizing video is such a daunting problem. Some people swear by hardware legalizers and say that's the only way to go.
Hardware legalizers can make it legal, but brute force ugly. You can get artifacts such as ugly splotches because they are "dumb". They don't have fancy routines or human eye to guide them for ideal fix . -
But you said sending 5-246, and saving it as a BMP was incorrect already.
Uncompressed RGB24 (or BGR24) in a container (e.g. AVI) is playable -
Yes uncompressed RGB24 AVI is playable in the ones I mentioned (MPCHC, MPV, a few others). But not all players
But you said sending 5-246, and saving it as a BMP was incorrect already.
I asked
"What is 0-255 ? RGB or YUV ? "
You said
"RGB, which as I said should be limited to 5 - 246."
How can RGB be 0-255, but your BMP is 5-246 ?
So you miscommunicated a few steps or I misunderstood a few things you did in between. What you really meant is you output RGB 5-246 from your program sent to ffmpeg (double checked that bmp is ok), converted to YUV somehow and then again to RGB somehow, and got RGB 0-255
I'm saying your RGB => YUV can be your "unity" when you work with the full range conversion (this is what RGB clipping for r103 means, it's done on studio range RGB 16-235, not computer range RGB) .
If you send RGB 5-246, you can have Y 5-246 with a full range conversion to YUV. That's what you're supposed to be doing . The broadcast checker uses the same studio range conversion for the RGB portion of the check so they get RGB 5-246. (And the pripr YUV to RGB conversion before your program should have used the full range conversion, otherwise your contrast will be wrong)
Perfect.
Not quite. This only works for YUV444. The problem is subsampling (and upsampling)
A group of 100% legal pixels can generate illegal values because of subsampling . You will get some pixels that show up as min/max of 0 or 255 (that are actually negative or >255)
Put a RGB 16,16,16 group of pixels beside a RGB 16,235,16 group of pixels. Black and green. Just 2 colors. When you convert to YUV444 it's still Y 16-235, because you're using studio range conversion. When the broadcast checker checks RGB range, you still get RGB 16-235 because it's using studio range too. It's easy to verify this. Perfect so far
BUT when you subsample,
1) you will get zeros in some channels during the RGB check stage because of subsampling and subsequent chroma upsampling in this example .
2) you can generate new YUV values in the middle of the range, that map to negative RGB values , or RGB >255 for 8bit (out of gamut, not in the RGB cube). Min/max clipping won't catch those.
Some chroma sampling algorithms can produce more or less illegal pixels, but all are prone. It's almost impossible not to generate at least some illegal pixels on typical content
When you only assess min/max individual pixels, you will miss combinations of pixels that when alone are legal, but in combination can generate illegal values
The big question is what % of the active image area is flagged, and what to do about those. Are you over the 1% limit ? Also distribution is important. Large clusters of illegal pixels can be produce very ugly results when you just clip them. But you can usually get away with single stray pixel clipping, here and there
Most software broadcast legalizers do the RGB check and indicate % of "bad" pixels and what areas (shown as a colored overlay or zebras) to see groupings of pixels and their relationships. Usually there are fast/automatic correction modes when you're in a hurry, and you can choose to either reduce saturation or increase/decrease levels, but they can produce very ugly results just like a hardware legalizer. You're supposed to use software legalizer in combination with human eye and manual intervention, but it takes time to do properly. -
-
It looks to be the same as this
http://avisynth.nl/index.php/Color_conversions
standard range
yuv [16,235] <-> rgb [0,255]
Code:y - 16 = (Kr*219/255)*r + (Kg*219/255)*g + (Kb*219/255)*b v - 128 = 112/255*r - Kg*112/255*g/(1-Kr) - Kb*112/255*b/(1-Kr) u - 128 = - Kr*112/255*r/(1-Kb) - Kg*112/255*g/(1-Kb) + 112/255*b r = (255/219)*y + (255/112)*v*(1-Kr) - (255*16/219 + 255*128/112*(1-Kr)) g = (255/219)*y - (255/112)*u*(1-Kb)*Kb/Kg - (255/112)*v*(1-Kr)*Kr/Kg - (255*16/219 - 255/112*128*(1-Kb)*Kb/Kg - 255/112*128*(1-Kr)*Kr/Kg) b = (255/219)*y + (255/112)*u*(1-Kb) - (255*16/219 + 255*128/112*(1-Kb))
And for full range
yuv [0,255] <-> rgb [0,255]
Code:y = Kr*r + Kg*g + Kb*b v - 128 = 0.5*(r-y)/(1-Kr) = 0.5 * r - 0.5 * g * Kg/(1-Kr) - 0.5 * b * Kb/(1-Kr) u - 128 = 0.5*(b-y)/(1-Kb) = - 0.5 * r * Kr/(1-Kb) - 0.5 * g * Kg/(1-Kb) + 0.5 * b r = y + 2*(v-128)*(1-Kr) g = y - 2*(u-128)*(1-Kb)*Kb/Kg - 2*(v-128)*(1-Kr)*Kr/Kg b = y + 2*(u-128)*(1-Kb)
-
It seems to work now.
I added this code when opening the output pipe:
Code:-vf scale=in_range=full:out_range=tv
-
Won't that mess up the contrast? That basically clamps levels. You would expect wrong black and white level, washed out, low constrast
Or maybe you're else doing something differently in other steps or conversions ?
A good way to check it is to run black and white test video through it. Y=16, Y=235. If the output YUV video does not have Y=16, Y=235, then the contrast is off. Maybe slightly off is acceptable. The 5-15, 236-246 are just for small excursions. The actual black , white level should be Y=16, Y=235
You can check your yuv420p output video with ffplay -i input.ext -vf waveform=g=green -
Last edited by chris319; 16th Feb 2020 at 17:15.
-
This is working pretty well so far:
Code:D:\Programs\ffmpeg\BroadcastVideo\ffmpeg -y -i "test_pattern_720.MP4" -c:v mpeg2video -pix_fmt rgb24 -vb 50M -minrate 50M -maxrate 50M -vf lutrgb='r=clip(val,6,245)',lutrgb='g=clip(val,6,245)',lutrgb='b=clip(val,6,245)',scale=out_color_matrix=bt709:out_range=limited -color_primaries bt709 -color_trc bt709 -colorspace bt709 -an -f vob clipped.mpg
There must be no data at 0 or 255 as these are sync levels in ATSC. -
You need to put down the whole path in cmd line and of course you need to have x264 downloaded in your PC in first place if using x264 encoder and not ffmpeg. ffmpeg alone is using some x264 library. Btw I hate ffmpeg, the whole thread in here basically is telling why. Defaults , defaults, defaults and you need to know exactly what to use in ffmpeg to override it or not allow it. If I can avoid it, I do that. There is a bunch of sources where to get x264.exe, for example: http://download.videolan.org/x264/binaries/win64/
Same for Nero encoder, mp4box . Those are tools that are dedicated for a particular job and they are doing it well.Last edited by _Al_; 16th Feb 2020 at 18:34.
-
I suspect you're using the wrong conversion to RGB prior to the clipping. You shouldn't have any "zeros" when you convert to RGB with standard colorbars . The only way you have that is when you use the standard conversion Y 16-235 => RGB 0,0,0 - 255,255,255. ie. the wrong equation for this situation. The only way you have zeros, is if you started with zeros. Because the proper equation is your "unity" Y 16-235 => RGB 16-235 (or Y 0-255 => RGB 0-255)
It also depends on what your input video is, and how it's flagged. How your input video is flagged can affect the input conversion for ffmpeg to rgb24, unless you explicitly override it.
When you use -pix_fmt rgb24 , it will normally use limited range 601 for unflagged video to convert to RGB . This means not only colors wrong, the levels will be wrong for r103 . Y 16-235 get mapped to RGB 0,0,0-255,255,255. The clipping will be at the wrong values, leading to the wrong contrast. The black and level in RGB will be 0 and 255. Definitely wrong for r103. Ok for computer.
Generating a test chart from 75% computer RGB (191 etc...) should use limited range (normal conversion) . Generating from 75% in studio range (180,16,16, etc..) should use full range equations + adjustment (if using current ffmpeg code). That's already established. That's only for the test chart generation. Recall that in both cases the YUV values were the same (or should be) . That's irrelevant now, you can file that away. Let's not discuss that anymore it's a different concluded topic
But a normal input video should use full range for the RGB clipping. That is what r103 means. Black and white reference points should be at 16, 235 for r103. Both RGB and YUV. That's your unity equation, or the full range equation
What you should be doing is full range conversion to RGB, clipping 5-246, full range out to YUV. So black is always at 16, white is always at 235. Both Y and RGB. You still have >5, <246, but those are just excursions. The actual black level is 16, actual white level is 235, so the contrast looks normal. r103 is using studio range RGB. That means prior when you convert to your RGB clipping stage, 75% red is now at RGB 180,16,16 , NOT RGB 191,0,0
The final check to RGB is ALSO done at studio range RGB (16-235). That's what the broadcast RGB checker does too. I suspect you're using standard conversion. When you're dealing with r103, everything is 16-235. (Again, the test chart generation itself is excluded, because the YUV values are the same eitherway, and you're not submitting RGB)Last edited by poisondeathray; 16th Feb 2020 at 19:02.
-
I think R103 is referring to limited range when it discusses RGB limits. Ie, converting limited range YUV to limited range RGB should keep RGB values between 5 and 246. This is really the only interpretation that makes sense. With a conversion to limited range RGB you can see how far off your RGB values are. With conversion to full range RGB all the out of gamut pixels would be pegged at 0 or 255 so you couldn't tell if they were out of gamut or not.
-
Exactly!
Jagabo is referring to the range of values . I used the name for the equations . It's the same thing
limited range RGB is "studio range RGB" or RGB 16-235
You convert YUV to limited range RGB by using the full range equations. Ie. 709 full range.
The problem is ffmpeg doesn't use the exact one that ITU or the one outlined there, it's slightly off a bit. The levels workaround makes it work -
-
What you say is true in theory, but the fly in the ointment is that ffmpeg forces levels to 255 in "full range", even when you tell it not to. That is the crux of this whole thread. So you have to use "limited range" instead. If things worked the way they should, and ffmpeg didn't have a mind of its own, it would be different.
You should really sit down and write some ffmpeg code and try this stuff out for yourself and you'll see what I mean. -
The next tricks is to output an XDCam file. Hey, it's what the client wants. Hopefully this is close.
Code:D:\Programs\ffmpeg\BroadcastVideo\ffmpeg -y -i "D:\videos\trains\c0015.MP4" -c:v mpeg2video -pix_fmt rgb24 -s 1280x720 -r 59.94 -vb 50M -minrate 50M -maxrate 50M -dc 10 -intra_vlc 1 -lmin "1*QP2LAMBDA" -qmin 1 -qmax 12 -vtag xd5c -non_linear_quant 1 -vf lutrgb='r=clip(val,6,246)',lutrgb='g=clip(val,6,246)',lutrgb='b=clip(val,6,246)',scale=out_color_matrix=bt709:out_range=limited -color_primaries bt709 -color_trc bt709 -colorspace bt709 -acodec pcm_s16le -pix_fmt yuv422p -profile:v 0 -level:v 2 -f mxf clipped.mxf
-
Here's what I'm referring to: Take a limited range rec.709 YUV value like 128,190,190. All three values are easily within their respective min/max limits. But is it a legal color? Converting to full range RGB gives 242,84,255. All three values legal for full range RGB. But any YUV color converted to full range RGB will result in a legal RGB value -- it's not possible to represent illegal values below 0 or above 255 with unsigned 8 bit bytes (all such values will always be clamped to 0 or 255). But converting to limited range RGB results in 226,87,244. 244 is outside the valid range of 16-235. So we know the YUV color was illegal. But it's still within the R103 "overshoot" range of 5-246.
-
What do you mean by full range? YUV values or RGB values? What part? And how are you determining this?
It works fine here. I just double checked everything I posted earlier. It doesn't "force" anything. FFmpeg does what you tell it to.
If I take Y 16-235, do full range 709 conversion , I get RGB 16-235. Do full range 709 conversion again and you get Y 16-235. That's your "unity", that's studio Range RGB, and r103 . I don't see a problem with that . If you had Y 0-255 to start with , you'd get RGB 0-255 too as expected. But your job is to limit Y to 16-235 (hopefully not by clipping)
Did you do what I suggested about adding more of the rp219 signals ? If I run your command on bars that include Y=16, 235 , you end up with Y=21, 226. So it is clamping the range . 75% Blue becomes YUV 33,209,120 instead of 28,212,120 . No doubt the min/max is "ok", but it's changing the contrast and colors . Too aggressive clamping and black/white level are off
Similar Threads
-
ffmpeg 4.1.4 question regarding "limited color range" output file
By bokeron2020 in forum Newbie / General discussionsReplies: 12Last Post: 1st Aug 2019, 17:28 -
Can I convert color profile with FFMPEG?
By PabstBlueRibbon in forum Video ConversionReplies: 0Last Post: 9th Sep 2017, 13:41 -
Color Range Question
By Akai-Shuichi in forum RestorationReplies: 4Last Post: 14th Feb 2017, 15:53 -
Change in color while reencoding with ffmpeg
By Epaminaidos in forum Video ConversionReplies: 24Last Post: 30th Sep 2016, 11:09 -
Can I alter h264 file's color range flags?
By bergqvistjl in forum Newbie / General discussionsReplies: 1Last Post: 17th Dec 2015, 12:00