1
mirror of https://github.com/mpv-player/mpv synced 2025-01-20 21:07:29 +01:00

Actually do something useful with XVID_GLOBAL_EXTRASTATS / XVID_EXTRASTATS.

Now we can really compare XviD and libavcodec :)


git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@9810 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
rguyom 2003-04-03 06:53:01 +00:00
parent 628526bb40
commit 9e88c30a9d
2 changed files with 73 additions and 6 deletions

View File

@ -3243,8 +3243,8 @@ subpel refinement quality (for qpel) (default: 8).
Note: This has a significant effect on the speed.
.IPs psnr
print the psnr (peak signal to noise ratio) for the whole video after encoding
and store the per frame psnr in a file with a name like 'psnr_012345.log'.
Return values are in dB (decibel), the higher the better.
and store the per frame psnr in a file with a name like 'psnr_hhmmss.log'.
Returned values are in dB (decibel), the higher the better.
.IPs mpeg_quant
use MPEG quantizers instead of H.263.
(default: disabled) (i.e.\& use H.263 quantizers)
@ -3463,6 +3463,10 @@ maximum number of B frames to put between I/P frames (default=0)
quantizer ratio between B and non B frames, 150=1.50 (default=150)
.IPs bquant_offset=<-1000\-1000>
quantizer offset between B and non B frames, 100=1.00 (default=100)
.IPs psnr
print the psnr (peak signal to noise ratio) for the whole video after encoding
and store the per frame psnr in a file with a name like 'psnr_hhmmss.log'.
Returned values are in dB (decibel), the higher the better.
.RE

View File

@ -2,6 +2,11 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#if !defined(INFINITY) && defined(HUGE_VAL)
#define INFINITY HUGE_VAL
#endif
#include "../config.h"
#include "../mp_msg.h"
@ -96,10 +101,11 @@ static int xvidenc_bquant_offset = 100;
static int xvidenc_gmc = 0;
static int xvidenc_chroma_me = 0;
static int xvidenc_reduced = 0;
static int xvidenc_xstat=0;
static int xvidenc_hqac=0;
static int xvidenc_vhq=0;
static int xvidenc_pref=0;
static int xvidenc_psnr=0;
static uint64_t xvid_error[3];
#endif
struct config xvidencopts_conf[] = {
@ -127,7 +133,7 @@ struct config xvidencopts_conf[] = {
{ "packed", &xvidenc_packed, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "divx5bvop", &xvidenc_divx5bvop, CONF_TYPE_FLAG, 0, 0, 1, NULL},
//{ "lumi_mask", &xvidenc_lumi_mask, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "extrastat", &xvidenc_xstat, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "psnr", &xvidenc_psnr, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "qpel", &xvidenc_qpel, CONF_TYPE_FLAG, 0, 0, 1, NULL},
{ "max_bframes", &xvidenc_max_bframes, CONF_TYPE_INT, CONF_RANGE, 0, 4, NULL},
{ "bquant_ratio", &xvidenc_bquant_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 1000, NULL},
@ -147,6 +153,8 @@ struct vf_priv_s {
XVID_ENC_FRAME enc_frame;
void* enc_handle;
vbr_control_t vbr_state;
int pixels;
int nb_frames;
};
static int
@ -224,8 +232,12 @@ config(struct vf_instance_s* vf,
enc_param.global |= XVID_GLOBAL_PACKED;
if (xvidenc_reduced)
enc_param.global |= XVID_GLOBAL_REDUCED;
if (xvidenc_xstat)
if (xvidenc_psnr) {
enc_param.global |= XVID_GLOBAL_EXTRASTATS;
fp->pixels = width * height;
fp->nb_frames = 0;
xvid_error[0] = xvid_error[1] = xvid_error[2] = 0;
}
#endif
if (xvidenc_greyscale)
enc_param.global |= XVID_GREYSCALE;
@ -269,7 +281,7 @@ config(struct vf_instance_s* vf,
fp->enc_frame.general |= XVID_MODEDECISION_BITS;
if (xvidenc_gmc)
fp->enc_frame.general |= XVID_GMC;
if (xvidenc_xstat)
if (xvidenc_psnr)
fp->enc_frame.general |= XVID_EXTRASTATS;
if (xvidenc_chroma_me)
fp->enc_frame.motion |= PMV_CHROMA16 | PMV_CHROMA8;
@ -350,11 +362,27 @@ config(struct vf_instance_s* vf,
return 1;
}
static double
sse_to_PSNR(double sse, double pixels)
{
return sse == 0 ? INFINITY : 4.34294481903251827652 * (11.08252709031685229249 - log(sse/pixels));
// 4.34294481903251827652 = 10/log(10)
// 11.08252709031685229249 = log(255*255)
}
static void
uninit(struct vf_instance_s* vf)
{
struct vf_priv_s *fp = vf->priv;
if (xvidenc_psnr) {
double p = (double)fp->pixels * (double)fp->nb_frames;
printf ("PSNR: Y:%2.2f, Cb:%2.2f, Cr:%2.2f, All:%2.2f\n",
sse_to_PSNR(xvid_error[0], p),
sse_to_PSNR(xvid_error[1], p/4),
sse_to_PSNR(xvid_error[2], p/4),
sse_to_PSNR(xvid_error[0] + xvid_error[1] + xvid_error[2], p*1.5));
}
vbrFinish(&fp->vbr_state);
}
@ -433,6 +461,41 @@ put_image(struct vf_instance_s* vf, mp_image_t *mpi)
mp_msg(MSGT_MENCODER, MSGL_ERR, "xvid: failure\n");
break;
}
if (xvidenc_psnr) {
static FILE *fvstats = NULL;
char filename[20];
if (!fvstats) {
time_t today2;
struct tm *today;
today2 = time (NULL);
today = localtime (&today2);
sprintf (filename, "psnr_%02d%02d%02d.log", today->tm_hour, today->tm_min, today->tm_sec);
fvstats = fopen (filename,"w");
if (!fvstats) {
perror ("fopen");
xvidenc_psnr = 0; // disable block
}
}
xvid_error[0] += enc_stats.sse_y;
xvid_error[1] += enc_stats.sse_u;
xvid_error[2] += enc_stats.sse_v;
fprintf (fvstats, "%6d, %2d, %6d, %2.2f, %2.2f, %2.2f, %2.2f %c\n",
fp->nb_frames,
enc_stats.quant,
fp->enc_frame.length,
sse_to_PSNR (enc_stats.sse_y, fp->pixels),
sse_to_PSNR (enc_stats.sse_u, fp->pixels / 4),
sse_to_PSNR (enc_stats.sse_v, fp->pixels / 4),
sse_to_PSNR (enc_stats.sse_y + enc_stats.sse_u + enc_stats.sse_v, (double)fp->pixels * 1.5),
fp->enc_frame.intra == 0 ? 'P' : fp->enc_frame.intra == 1 ? 'I' : 'B'
);
fp->nb_frames++;
}
// write output
muxer_write_chunk(fp->mux, fp->enc_frame.length, fp->enc_frame.intra==1 ? 0x10 : 0);