Mercurial > libavcodec.hg
changeset 252:ddb1a0e94cf4 libavcodec
- 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.
author | pulento |
---|---|
date | Tue, 26 Feb 2002 22:14:27 +0000 |
parents | 75091bfc577b |
children | 4448dd55d415 |
files | Makefile avcodec.h dsputil.c dsputil.h i386/mpegvideo_mmx.c mpegvideo.c |
diffstat | 6 files changed, 66 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- 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 \
--- 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 */
--- 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 <stdlib.h> #include <stdio.h> +#include <math.h> #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;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; +} +
--- 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
--- 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;
--- 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; }