[FFmpeg-trac] #9781(avfilter:closed): zscale adds distortion when resampling video data

FFmpeg trac at avcodec.org
Fri May 13 15:35:57 EEST 2022


#9781: zscale adds distortion when resampling video data
-------------------------------------+-------------------------------------
             Reporter:  Llyw         |                    Owner:  (none)
                 Type:  defect       |                   Status:  closed
             Priority:  normal       |                Component:  avfilter
              Version:  git-master   |               Resolution:  fixed
             Keywords:  zscale       |               Blocked By:
  distortion                         |
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
Comment (by Llyw):

 Thanks for taking the time to take a look at this, Paul!

 I took a look at your changes and I think I am beginning to understand the
 issue with the previous implementation: Essentially, the previous
 implementation computed the active input area based on the job index and
 number of jobs. Ignoring the adjustment to make the slice offsets
 divisible by four and denoting the input height with `ih`, the output
 height with `oh`, and the number of threads with `n`, the previous
 implementation would thus assign an implicit resample ratio of `(ih %
 floor(ih/n))/(oh % floor(oh/n))` to the last slice, and a resample ratio
 of `floor(ih/n)/floor(oh/n)` to all others if `oh` was not divisible by
 `n` and `n>1`. These ratios can differ significantly, leading to observed
 distortion, and are bad approximations to the actual resample ratio
 `ih/oh`.

 Your commit improves this by computing the active input area based on the
 actual resample ratio `ih/oh` instead. This will reduce the distortion
 when `oh` is not divisible by `n` and `n > 1`, since the resample ratio of
 the last slice `floor(((oh % ceil(oh/n)) * ih)/oh)/(oh % ceil(oh/n))` will
 be closer to `floor((ceil(oh/n) * ih)/oh)/ceil(oh/n)`, with both
 expressions being closer to `ih/oh` than the previous approximation. (When
 `ceil(oh/n)` is odd, you need to replace it with `ceil(oh/n)+1` in the
 above expressions.)

 To reduce distortion, one should therefore at least ensure that `oh` is
 divisible by `s` where `s` is equal to `floor((ceil(oh/n) + 1)/2)` or
 choose `n=1`. For `n>1`, having `oh` being divisible by `s` is still no
 guarantee for no distortion, however, you would also need `s * ih` to be
 divisible by `oh` for that.

 I did take a look at the z.lib/zimg API and it seems that the active area
 does not have to be specified as an integer but is stored as floating-
 point values, so a future improvement would be to use double precision
 floating-point values when computing the active area of the input for each
 output slice. Until then the filter may still show some distortion
 depending on the input dimensions, output dimensions, and the thread
 count. (I would honestly appreciate it if this defect would remain open
 until this improvement is realized but am hesitant to re-open it myself.)
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/9781#comment:6>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list