diff mbox series

[FFmpeg-devel,RFC/PATCH] fftools/ffmpeg: stop printing PSNR information in status report

Message ID 20230419194832.757-1-anton@khirnov.net
State Accepted
Commit 87b4453ec6df4de78a9ede6abccdfefe7cfeb66a
Headers show
Series [FFmpeg-devel,RFC/PATCH] fftools/ffmpeg: stop printing PSNR information in status report | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov April 19, 2023, 7:48 p.m. UTC
When an encoder exports sum-of-squared-differences information in
encoded packets, print_report() will print PSNR information in the
status line. However,
* the code computing PSNR assumes 8bit 420 video and prints incorrect
  values otherwise; there are no issues on trac about this
* only a few encoders (namely aom, vpx, mpegvideo, snow) export this
  information; other often-used encoders such as libx26[45] do not
  export this, even though they could

This suggests that this feature is not useful and it is better to remove
it rather than spend effort on fixing it.
---
I needed to resolve this code's interaction with encoders as a part of
my multithreading work and spent a few hours on it. Making it work
correctly in all cases seems nontrivial and duplicates a lot of the
logic from vf_psnr.

Given that nobody ever noticed that it's broken for everything other
than YUV420P, or bothered adding support in libx264 strongly suggests to
me that nobody cares about this and it can be safely dropped.

Anyone against?
---
 fftools/ffmpeg.c | 30 ------------------------------
 1 file changed, 30 deletions(-)

Comments

Michael Niedermayer April 19, 2023, 8:53 p.m. UTC | #1
On Wed, Apr 19, 2023 at 09:48:32PM +0200, Anton Khirnov wrote:
> When an encoder exports sum-of-squared-differences information in
> encoded packets, print_report() will print PSNR information in the
> status line. However,

> * the code computing PSNR assumes 8bit 420 video and prints incorrect
>   values otherwise; there are no issues on trac about this

Are the values in the "otherwise" case maybe good enough so they
worked for people with noone noticing ?


> * only a few encoders (namely aom, vpx, mpegvideo, snow) export this
>   information; other often-used encoders such as libx26[45] do not
>   export this, even though they could
> 
> This suggests that this feature is not useful and it is better to remove
> it rather than spend effort on fixing it.
> ---
> I needed to resolve this code's interaction with encoders as a part of
> my multithreading work and spent a few hours on it. Making it work
> correctly in all cases seems nontrivial and duplicates a lot of the
> logic from vf_psnr.

Can anything missing in vf_psnr be added into it and then vf_psnr used ?
I agree that duplicating PSNR code and logic is bad


> 
> Given that nobody ever noticed that it's broken for everything other
> than YUV420P, or bothered adding support in libx264 strongly suggests to
> me that nobody cares about this and it can be safely dropped.
> 
> Anyone against?

[...]
Anton Khirnov April 19, 2023, 9:06 p.m. UTC | #2
Quoting Michael Niedermayer (2023-04-19 22:53:02)
> On Wed, Apr 19, 2023 at 09:48:32PM +0200, Anton Khirnov wrote:
> > When an encoder exports sum-of-squared-differences information in
> > encoded packets, print_report() will print PSNR information in the
> > status line. However,
> 
> > * the code computing PSNR assumes 8bit 420 video and prints incorrect
> >   values otherwise; there are no issues on trac about this
> 
> Are the values in the "otherwise" case maybe good enough so they
> worked for people with noone noticing ?

While working on this with a 10bit sample I was suprised this code and
vf_psnr showed significantly different values (IIRC not even the first
digit was accurate) and it took me a while to realize the scaling made
the assumptions it did.

> > * only a few encoders (namely aom, vpx, mpegvideo, snow) export this
> >   information; other often-used encoders such as libx26[45] do not
> >   export this, even though they could
> > 
> > This suggests that this feature is not useful and it is better to remove
> > it rather than spend effort on fixing it.
> > ---
> > I needed to resolve this code's interaction with encoders as a part of
> > my multithreading work and spent a few hours on it. Making it work
> > correctly in all cases seems nontrivial and duplicates a lot of the
> > logic from vf_psnr.
> 
> Can anything missing in vf_psnr be added into it and then vf_psnr used ?
> I agree that duplicating PSNR code and logic is bad

Nothing is missing in vf_psnr AFAIK, the difference is that these values
are produced directly by the encoder, so you don't need a
decoding+filtering pass to obtain the numbers.

The question more broadly is - what is this supposed to be useful for?
PSNR is a highly flawed metric and AFAIU state of the art moved several
generations away from it. And for a quick-and-dirty quality estimate,
the bitrate and QP might be more informative for most users, and are
supported by more encoders. So what is the point of printing this
information?
Michael Niedermayer April 19, 2023, 10:12 p.m. UTC | #3
On Wed, Apr 19, 2023 at 11:06:09PM +0200, Anton Khirnov wrote:
> Quoting Michael Niedermayer (2023-04-19 22:53:02)
> > On Wed, Apr 19, 2023 at 09:48:32PM +0200, Anton Khirnov wrote:
> > > When an encoder exports sum-of-squared-differences information in
> > > encoded packets, print_report() will print PSNR information in the
> > > status line. However,
> > 
> > > * the code computing PSNR assumes 8bit 420 video and prints incorrect
> > >   values otherwise; there are no issues on trac about this
> > 
> > Are the values in the "otherwise" case maybe good enough so they
> > worked for people with noone noticing ?
> 
> While working on this with a 10bit sample I was suprised this code and
> vf_psnr showed significantly different values (IIRC not even the first
> digit was accurate) and it took me a while to realize the scaling made
> the assumptions it did.
> 
> > > * only a few encoders (namely aom, vpx, mpegvideo, snow) export this
> > >   information; other often-used encoders such as libx26[45] do not
> > >   export this, even though they could
> > > 
> > > This suggests that this feature is not useful and it is better to remove
> > > it rather than spend effort on fixing it.
> > > ---
> > > I needed to resolve this code's interaction with encoders as a part of
> > > my multithreading work and spent a few hours on it. Making it work
> > > correctly in all cases seems nontrivial and duplicates a lot of the
> > > logic from vf_psnr.
> > 
> > Can anything missing in vf_psnr be added into it and then vf_psnr used ?
> > I agree that duplicating PSNR code and logic is bad
> 
> Nothing is missing in vf_psnr AFAIK, the difference is that these values
> are produced directly by the encoder, so you don't need a
> decoding+filtering pass to obtain the numbers.

That sounds like a missing feature.
vf_psnr cannot use the encoder values, it always needs to recompute them.
The encoder could export these values in metadata and vf_psnr could
then check if the frame pairs already have their psnr computed and use
that.


> 
> The question more broadly is - what is this supposed to be useful for?
> PSNR is a highly flawed metric and AFAIU state of the art moved several
> generations away from it. And for a quick-and-dirty quality estimate,
> the bitrate and QP might be more informative for most users, and are
> supported by more encoders. So what is the point of printing this
> information?

The "problem" isnt psnr specific
having a filter which could provide another metric and be able to use
encoder supplied data when available or compute them from encoder input +
decoded images in a way that is automatic would be useful
It would mean a single syntax a user could use to get the metric he wants
while using the optimal implementation

thx

[...]
Anton Khirnov April 20, 2023, 6:42 a.m. UTC | #4
Quoting Michael Niedermayer (2023-04-20 00:12:48)
> On Wed, Apr 19, 2023 at 11:06:09PM +0200, Anton Khirnov wrote:
> > Quoting Michael Niedermayer (2023-04-19 22:53:02)
> > > On Wed, Apr 19, 2023 at 09:48:32PM +0200, Anton Khirnov wrote:
> > > > When an encoder exports sum-of-squared-differences information in
> > > > encoded packets, print_report() will print PSNR information in the
> > > > status line. However,
> > > 
> > > > * the code computing PSNR assumes 8bit 420 video and prints incorrect
> > > >   values otherwise; there are no issues on trac about this
> > > 
> > > Are the values in the "otherwise" case maybe good enough so they
> > > worked for people with noone noticing ?
> > 
> > While working on this with a 10bit sample I was suprised this code and
> > vf_psnr showed significantly different values (IIRC not even the first
> > digit was accurate) and it took me a while to realize the scaling made
> > the assumptions it did.
> > 
> > > > * only a few encoders (namely aom, vpx, mpegvideo, snow) export this
> > > >   information; other often-used encoders such as libx26[45] do not
> > > >   export this, even though they could
> > > > 
> > > > This suggests that this feature is not useful and it is better to remove
> > > > it rather than spend effort on fixing it.
> > > > ---
> > > > I needed to resolve this code's interaction with encoders as a part of
> > > > my multithreading work and spent a few hours on it. Making it work
> > > > correctly in all cases seems nontrivial and duplicates a lot of the
> > > > logic from vf_psnr.
> > > 
> > > Can anything missing in vf_psnr be added into it and then vf_psnr used ?
> > > I agree that duplicating PSNR code and logic is bad
> > 
> > Nothing is missing in vf_psnr AFAIK, the difference is that these values
> > are produced directly by the encoder, so you don't need a
> > decoding+filtering pass to obtain the numbers.
> 
> That sounds like a missing feature.
> vf_psnr cannot use the encoder values, it always needs to recompute them.
> The encoder could export these values in metadata and vf_psnr could
> then check if the frame pairs already have their psnr computed and use
> that.

In general I agree that making those values more widely usable would be
good, but there's a number of issues that would need to be addressed
first:
* encoders export encoded packet properties, but AFAIK no muxer can
  store them
* even if a muxer could store them or encoded packets could be directly
  passed to a decoder (this should actually be possible once I'm done
  with this work), the data is only defined for packets and not frames
* possibly something like showinfo would be more suited for displaying
  this
None of these are insurmountable, but it's a fair amount of work.
Patches welcome.

> > The question more broadly is - what is this supposed to be useful for?
> > PSNR is a highly flawed metric and AFAIU state of the art moved several
> > generations away from it. And for a quick-and-dirty quality estimate,
> > the bitrate and QP might be more informative for most users, and are
> > supported by more encoders. So what is the point of printing this
> > information?
> 
> The "problem" isnt psnr specific
> having a filter which could provide another metric and be able to use
> encoder supplied data when available or compute them from encoder input +
> decoded images in a way that is automatic would be useful
> It would mean a single syntax a user could use to get the metric he wants
> while using the optimal implementation

The problem is PSNR-specific code in ffmpeg CLI that is blocking my
work. Sounds to me we are in agreement that this code should not be
there.
Anton Khirnov April 22, 2023, 3:41 p.m. UTC | #5
If nobody has more comments or objections, I'm planning to push this on
Monday.
diff mbox series

Patch

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index a7e856e9e2..c73064af9a 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -767,36 +767,6 @@  static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
             if (is_last_report)
                 av_bprintf(&buf, "L");
 
-            if (enc && (enc->flags & AV_CODEC_FLAG_PSNR) &&
-                (ost->pict_type != AV_PICTURE_TYPE_NONE || is_last_report)) {
-                int j;
-                double error, error_sum = 0;
-                double scale, scale_sum = 0;
-                double p;
-                char type[3] = { 'Y','U','V' };
-                av_bprintf(&buf, "PSNR=");
-                for (j = 0; j < 3; j++) {
-                    if (is_last_report) {
-                        error = enc->error[j];
-                        scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;
-                    } else {
-                        error = ost->error[j];
-                        scale = enc->width * enc->height * 255.0 * 255.0;
-                    }
-                    if (j)
-                        scale /= 4;
-                    error_sum += error;
-                    scale_sum += scale;
-                    p = psnr(error / scale);
-                    av_bprintf(&buf, "%c:%2.2f ", type[j], p);
-                    av_bprintf(&buf_script, "stream_%d_%d_psnr_%c=%2.2f\n",
-                               ost->file_index, ost->index, type[j] | 32, p);
-                }
-                p = psnr(error_sum / scale_sum);
-                av_bprintf(&buf, "*:%2.2f ", psnr(error_sum / scale_sum));
-                av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n",
-                           ost->file_index, ost->index, p);
-            }
             vid = 1;
         }
         /* compute min output value */