- Added PSNR feature to libavcodec and ffmpeg. By now just Y PSNR until I'm

sure it works ok. Also it's slow, so use it only when you _really_ need to
measure quality.
- Fix libavcodec Makefile to enable profiling.

Originally committed as revision 314 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Juanjo 2002-02-26 22:14:27 +00:00
parent 2b9ab1d54a
commit 43f1708f8b
7 changed files with 76 additions and 8 deletions

View File

@ -98,6 +98,7 @@ static char *str_comment = NULL;
static int do_benchmark = 0;
static int do_hex_dump = 0;
static int do_play = 0;
static int do_psnr = 0;
typedef struct AVOutputStream {
int file_index; /* file index */
@ -958,6 +959,8 @@ static int av_encode(AVFormatContext **output_files,
frame_number = ist->frame_number;
sprintf(buf + strlen(buf), "frame=%5d q=%2d ",
frame_number, enc->quality);
if (do_psnr)
sprintf(buf + strlen(buf), "PSNR=%6.2f ", enc->psnr_y);
vid = 1;
}
/* compute min pts value */
@ -1006,6 +1009,8 @@ static int av_encode(AVFormatContext **output_files,
frame_number = ist->frame_number;
sprintf(buf + strlen(buf), "frame=%5d q=%2d ",
frame_number, enc->quality);
if (do_psnr)
sprintf(buf + strlen(buf), "PSNR=%6.2f ", enc->psnr_y);
vid = 1;
}
/* compute min pts value */
@ -1618,6 +1623,10 @@ void opt_output_file(const char *filename)
video_enc->flags |= CODEC_FLAG_QSCALE;
video_enc->quality = video_qscale;
}
if (do_psnr)
video_enc->get_psnr = 1;
else
video_enc->get_psnr = 0;
/* XXX: need to find a way to set codec parameters */
if (oc->format == &ppm_format ||
oc->format == &ppmpipe_format) {
@ -1960,6 +1969,7 @@ const OptionDef options[] = {
"add timings for benchmarking" },
{ "hex", OPT_BOOL | OPT_EXPERT, {(void*)&do_hex_dump},
"dump each input packet" },
{ "psnr", OPT_BOOL | OPT_EXPERT, {(void*)&do_psnr}, "calculate PSNR of compressed frames" },
{ NULL, },
};

View File

@ -16,6 +16,11 @@ OBJS+= ac3dec.o \
libac3/imdct.o libac3/parse.o
endif
ifeq ($(TARGET_GPROF),yes)
CFLAGS+=-p
LDFLAGS+=-p
endif
# i386 mmx specific stuff
ifeq ($(TARGET_MMX),yes)
OBJS += i386/fdct_mmx.o i386/cputest.o \

View File

@ -123,6 +123,12 @@ typedef struct AVCodecContext {
/* with a Start Code (it should) H.263 does */
void (*rtp_callback)(void *data, int size, int packet_number);
/* These are for PSNR calculation, if you set get_psnr to 1 */
/* after encoding you will have the PSNR on psnr_y/cb/cr */
int get_psnr;
float psnr_y;
float psnr_cb;
float psnr_cr;
/* the following fields are ignored */
void *opaque; /* can be used to carry app specific stuff */

View File

@ -18,6 +18,7 @@
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "avcodec.h"
#include "dsputil.h"
#include "simple_idct.h"
@ -576,3 +577,37 @@ void dsputil_init(void)
build_zigzag_end();
}
void get_psnr(UINT8 *orig_image[3], UINT8 *coded_image[3],
int orig_linesize[3], int coded_linesize,
AVCodecContext *avctx)
{
int quad, diff, x, y;
UINT8 *orig, *coded;
UINT32 *sq = squareTbl + 256;
quad = 0;
diff = 0;
/* Luminance */
orig = orig_image[0];
coded = coded_image[0];
for (y=0;y<avctx->height;y++) {
for (x=0;x<avctx->width;x++) {
diff = *(orig + x) - *(coded + x);
quad += sq[diff];
}
orig += orig_linesize[0];
coded += coded_linesize;
}
avctx->psnr_y = (float) quad / (float) (avctx->width * avctx->height);
if (avctx->psnr_y) {
avctx->psnr_y = (float) (255 * 255) / avctx->psnr_y;
avctx->psnr_y = 10 * (float) log10 (avctx->psnr_y);
} else
avctx->psnr_y = 99.99;
}

View File

@ -2,6 +2,7 @@
#define DSPUTIL_H
#include "common.h"
#include "avcodec.h"
/* dct code */
typedef short DCTELEM;
@ -138,4 +139,9 @@ void dsputil_init_alpha(void);
#endif
/* PSNR */
void get_psnr(UINT8 *orig_image[3], UINT8 *coded_image[3],
int orig_linesize[3], int coded_linesize,
AVCodecContext *avctx);
#endif

View File

@ -96,14 +96,14 @@ static void dct_unquantize_h263_mmx(MpegEncContext *s,
block[0] = block[0] * s->c_dc_scale;
}
for(i=1; i<8; i++) {
level = block[i];
if (level) {
if (level < 0) {
level = level * qmul - qadd;
} else {
level = level * qmul + qadd;
}
block[i] = level;
level = block[i];
if (level) {
if (level < 0) {
level = level * qmul - qadd;
} else {
level = level * qmul + qadd;
}
block[i] = level;
}
}
nCoeffs=64;

View File

@ -522,6 +522,12 @@ int MPV_encode_picture(AVCodecContext *avctx,
s->total_bits += (pbBufPtr(&s->pb) - s->pb.buf) * 8;
avctx->quality = s->qscale;
if (avctx->get_psnr) {
/* At this point pict->data should have the original frame */
/* an s->current_picture should have the coded/decoded frame */
get_psnr(pict->data, s->current_picture,
pict->linesize, s->linesize, avctx);
}
return pbBufPtr(&s->pb) - s->pb.buf;
}