# HG changeset patch # User pulento # Date 1014761667 0 # Node ID ddb1a0e94cf4922dbb5ec1792a46aca7259ac5e5 # Parent 75091bfc577b9ebadc450c356f79d3832a4836b8 - 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. diff -r 75091bfc577b -r ddb1a0e94cf4 Makefile --- a/Makefile Fri Feb 22 19:19:01 2002 +0000 +++ b/Makefile Tue Feb 26 22:14:27 2002 +0000 @@ -16,6 +16,11 @@ 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 \ diff -r 75091bfc577b -r ddb1a0e94cf4 avcodec.h --- a/avcodec.h Fri Feb 22 19:19:01 2002 +0000 +++ b/avcodec.h Tue Feb 26 22:14:27 2002 +0000 @@ -123,6 +123,12 @@ /* 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 */ diff -r 75091bfc577b -r ddb1a0e94cf4 dsputil.c --- a/dsputil.c Fri Feb 22 19:19:01 2002 +0000 +++ b/dsputil.c Tue Feb 26 22:14:27 2002 +0000 @@ -18,6 +18,7 @@ */ #include #include +#include #include "avcodec.h" #include "dsputil.h" #include "simple_idct.h" @@ -576,3 +577,37 @@ 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;yheight;y++) { + for (x=0;xwidth;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; +} + diff -r 75091bfc577b -r ddb1a0e94cf4 dsputil.h --- a/dsputil.h Fri Feb 22 19:19:01 2002 +0000 +++ b/dsputil.h Tue Feb 26 22:14:27 2002 +0000 @@ -2,6 +2,7 @@ #define DSPUTIL_H #include "common.h" +#include "avcodec.h" /* dct code */ typedef short DCTELEM; @@ -138,4 +139,9 @@ #endif +/* PSNR */ +void get_psnr(UINT8 *orig_image[3], UINT8 *coded_image[3], + int orig_linesize[3], int coded_linesize, + AVCodecContext *avctx); + #endif diff -r 75091bfc577b -r ddb1a0e94cf4 i386/mpegvideo_mmx.c --- a/i386/mpegvideo_mmx.c Fri Feb 22 19:19:01 2002 +0000 +++ b/i386/mpegvideo_mmx.c Tue Feb 26 22:14:27 2002 +0000 @@ -96,14 +96,14 @@ 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; diff -r 75091bfc577b -r ddb1a0e94cf4 mpegvideo.c --- a/mpegvideo.c Fri Feb 22 19:19:01 2002 +0000 +++ b/mpegvideo.c Tue Feb 26 22:14:27 2002 +0000 @@ -522,6 +522,12 @@ 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; }