On Mon, Sep 14, 2020 at 2:44 PM Michael Niedermayer <mich...@niedermayer.cc> wrote:
> On Sun, Sep 13, 2020 at 04:04:42PM -0700, Mark Reid wrote: > > On Sun, Sep 13, 2020 at 8:55 AM Michael Niedermayer > <mich...@niedermayer.cc> > > wrote: > > > > > On Sat, Sep 12, 2020 at 02:07:14AM -0700, mindm...@gmail.com wrote: > > > > From: Mark Reid <mindm...@gmail.com> > > > > > > > > --- > > > > libswscale/input.c | 12 +++++------- > > > > tests/ref/fate/filter-pixfmts-scale | 8 ++++---- > > > > 2 files changed, 9 insertions(+), 11 deletions(-) > > > > > > Can you provide some tests that show that this is better ? > > > Iam asking that because some of the numbers in some of the code > > > (i dont remember which) where tuned to give more accurate overall > results > > > > > > an example for tests would be converting from A->B->A then compare to > the > > > orig > > > > > > thx > > > > > > > > Hopefully i can explain this clearly! > > > > It's easier to see the error if you run a black image through the old > > conversion. > > zero values don't get mapped to zero. (attached sample image) > > > > ffmpeg -i 4x4_zero.exr -pix_fmt rgb48le -f rawvideo 4x4_zero.rawvideo > > The image should be rgb 0, 0, 0 everywhere but instead it's 353, 0, 407 > > > > > > I think this is a error in fixed point rounding, the issue is basically > > boils down to > > > > 128 << 8 != 257 << 7 > > and > > 16 << 8 != 33 << 7 > > > > https://en.wikipedia.org/wiki/YUV#Studio_swing_for_BT.601 > > the 8 bit rgb to yuv formula is > > > > Y = ry*r + gy*g + by*b + 16 > > U = ru*r + gu*g + bu*b + 128 > > V = rv*r + gv*g + bv*b + 128 > > > > I think the studio swing offsets at the end are calculated wrong in the > old > > code. > > (257 << (RGB2YUV_SHIFT + bpc - 9))) > > 257 is correct for 8 bit rounding but not for 16-bit. > > > > the 257 i believe is from (128 << 1) + 1 > > the +1 is for rounding > > > > for rounding 16-bit (128 << 9) + 1 = 0x10001 > > > > therefore I think the correct rounding any bit depth with the old formula > > would be (untested) > > (((128 << (bpc - 7)) + 1) << (RGB2YUV_SHIFT-1) ) > > > > I just simplified it to > > (0x10001 << (RGB2YUV_SHIFT - 1)) > > > > The rgb48ToUV and rgb48ToY funcs in input.c use the formula I'm using. > > You quite possibly are correct, can you test that this actually works > out. The test sample only covers 1 color (black) > a testsample covering a wide range of the color cube would be more > convincing that this change is needed and sufficient to fix this. > > thx > I wrote a small python script to compare the raw gbrpf32le images if that works? I attached it and also a more colorful test pattern. it runs these two commands and compares the 2 raw float images ffmpeg -y -i test_pattern.exr -f rawvideo original.gbrpf32le ffmpeg -y -i test_pattern.exr -vf format=pix_fmts=rgb48le,format=pix_fmts=gbrpf32le -f rawvideo converted.gbrpf32le python gbrpf32le_diff.py test_pattern.exr without patch: avg error: 237.445495855 min error: 0.0 max error: 468.399102688 with patch: avg error: 15.9312244829 min error: 0.0 max error: 69.467689991 These are floating points scaled to 16-bit values. Even with my patch, I'm kinda disturbed how much error there is. > > [...] > > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > There will always be a question for which you do not know the correct > answer. > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
from __future__ import print_function import struct import sys import subprocess FFMPEG = './ffmpeg' def read_f32(f): return struct.unpack("<f", f.read(4))[0] def generate(path): out_file1 = "original.gbrpf32le" cmd = [FFMPEG, '-y', '-i', path, '-f', 'rawvideo', out_file1] print(subprocess.list2cmdline(cmd)) subprocess.check_call(cmd) out_file2 = "converted.gbrpf32le" cmd = [FFMPEG, '-y', '-i', path, '-vf', 'format=pix_fmts=rgb48le,format=pix_fmts=gbrpf32le', '-f', 'rawvideo', out_file2] print(subprocess.list2cmdline(cmd)) subprocess.check_call(cmd) return out_file1, out_file2 # file1 = sys.argv[1] # file2 = sys.argv[2] file1, file2 = generate(sys.argv[1]) pix_count = 0 error_sum = 0.0 min_error = 1.0 max_error = 0.0 with open(file1, 'rb') as f1: with open(file2, 'rb') as f2: while True: try: v1 = read_f32(f1) v2 = read_f32(f2) diff = abs(v1 - v2) min_error = min(min_error, diff) max_error = max(max_error, diff) error_sum += diff pix_count += 1 except: break print("values:", pix_count) print("avg error: {}\nmin error: {}\nmax error: {}".format(error_sum / pix_count * 0xFFFF, min_error* 0xFFFF, max_error* 0xFFFF)) # without patch # avg error: 237.445495855 # min error: 0.0 # max error: 468.399102688 # with patch # avg error: 15.9312244829 # min error: 0.0 # max error: 69.467689991
test_pattern.exr
Description: Binary data
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".