From: Roman S. <rv...@su...> - 2003-11-27 02:17:25
|
Please note that I've renamed dv.h from libdv to libdv.h and dv_types.h into libdv_types.h: $ cc -I. -Iffmpeg/libavcodec test.c libdv.a ffmpeg/libavcodec/libavcodec.a -lm -o test $ cat test.c #include <stdlib.h> #include <stdio.h> #include <math.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/times.h> #include <limits.h> #include "avcodec.h" #include "libdv.h" #define RAW_FRAME_H 480 #define RAW_FRAME_W 720 #define RAW_FRAME_SIZE (RAW_FRAME_H*RAW_FRAME_W*2) AVFrame *alloc_picture(int pix_fmt, int width, int height) { AVFrame *picture; uint8_t *picture_buf; int size; picture = avcodec_alloc_frame(); if (!picture) return NULL; size = avpicture_get_size(pix_fmt, width, height); picture_buf = malloc(size); if (!picture_buf) { av_free(picture); return NULL; } avpicture_fill((AVPicture *)picture, picture_buf, pix_fmt, width, height); return picture; } long long frame_mse(uint8_t *x, uint8_t* y) { long long sum = 0; int i; for (i=0; i<RAW_FRAME_SIZE; i++) sum += ((long long)x[i] - (long long)y[i]) * ((long long)x[i] - (long long)y[i]); return sum; } float PSNR(long double MSE) { return (float)(20*log10(255/sqrt((double)MSE))); } int main(int argc, char **argv) { AVCodec *av_decoder; AVCodec *av_encoder; dv_decoder_t *dv_decoder; dv_encoder_t *dv_encoder; AVCodecContext *av_encoder_ctx; AVCodecContext *av_decoder_ctx; AVFrame *picture422, *picture411; AVFrame *picture_ptr; uint8_t dv_buffer[144000]; uint8_t original_frame[RAW_FRAME_SIZE]; uint8_t test_frame[RAW_FRAME_SIZE]; FILE* fptr = (argc == 2 ? stdin : fopen(argv[2], "r")); unsigned char *pixels[3]; int pitches[3]; int iter; int i, dummy; int total_frames = 0; long double DV_MSE[255]; long double AV_MSE[255]; clock_t dv_time_enc = 0; clock_t av_time_enc = 0; clock_t dv_time_dec = 0; clock_t av_time_dec = 0; struct tms tmp_time[2]; /* Generic setup */ iter = atoi(argv[1]); for (i=0; i<iter; i++) DV_MSE[i] = AV_MSE[i] = 0; /* libdv setup section */ dv_decoder = dv_decoder_new(FALSE, FALSE, FALSE); dv_decoder->quality = DV_QUALITY_BEST; dv_decoder->clamp_luma = FALSE; dv_decoder->clamp_chroma = FALSE; dv_decoder->add_ntsc_setup = FALSE; dv_encoder = dv_encoder_new(FALSE, FALSE, FALSE); dv_encoder->vlc_encode_passes = 3; dv_encoder->static_qno = 0; dv_encoder->force_dct = DV_DCT_AUTO; dv_encoder->clamp_luma = FALSE; dv_encoder->clamp_chroma = FALSE; dv_encoder->rem_ntsc_setup = FALSE; dv_encoder->isPAL = FALSE; /* FIXME */ dv_encoder->is16x9 = FALSE; pitches[0] = 720 * 2; /* libavcodec setup section */ register_avcodec(&dvvideo_decoder); av_encoder_ctx = avcodec_alloc_context(); av_decoder_ctx = avcodec_alloc_context(); av_decoder = avcodec_find_decoder(CODEC_ID_DVVIDEO); av_encoder = avcodec_find_encoder(CODEC_ID_DVVIDEO); av_encoder_ctx->width = RAW_FRAME_W; av_encoder_ctx->height = RAW_FRAME_H; avcodec_open(av_encoder_ctx, av_encoder); avcodec_open(av_decoder_ctx, av_decoder); picture422 = alloc_picture(PIX_FMT_YUV422, RAW_FRAME_W, RAW_FRAME_H); picture411 = alloc_picture(PIX_FMT_YUV411P, RAW_FRAME_W, RAW_FRAME_H); /* picture420 = alloc_picture(PIX_FMT_YUV411, RAW_FRAME_W, RAW_FRAME_H); */ while (fread(&original_frame, 1, RAW_FRAME_SIZE, fptr) == RAW_FRAME_SIZE) { /* A bit of a setup */ ++total_frames; /* Let's try libdv first */ memcpy(test_frame, original_frame, RAW_FRAME_SIZE); pixels[0] = test_frame; for (i=0; i<iter; i++) { /* Encoding */ times(&tmp_time[0]); dv_encode_full_frame(dv_encoder, pixels, e_dv_color_yuv, dv_buffer); times(&tmp_time[1]); dv_time_enc += (tmp_time[1].tms_utime - tmp_time[0].tms_utime); /* Decoding */ dv_parse_header(dv_decoder, dv_buffer); times(&tmp_time[0]); dv_decode_full_frame(dv_decoder, dv_buffer, e_dv_color_yuv, pixels, pitches); times(&tmp_time[1]); dv_time_dec += (tmp_time[1].tms_utime - tmp_time[0].tms_utime); DV_MSE[i] = DV_MSE[i] + (long double)frame_mse(original_frame, test_frame)/RAW_FRAME_SIZE; } /* Then we try libavcodec */ memcpy(picture422->data[0], original_frame, RAW_FRAME_SIZE); for (i=0; i<iter; i++) { img_convert((AVPicture *)picture411, PIX_FMT_YUV411P, (AVPicture *)picture422, PIX_FMT_YUV422, RAW_FRAME_W, RAW_FRAME_H); picture_ptr = picture411; /* Encoding */ times(&tmp_time[0]); avcodec_encode_video(av_encoder_ctx, dv_buffer, sizeof(dv_buffer), picture_ptr); times(&tmp_time[1]); av_time_enc += (tmp_time[1].tms_utime - tmp_time[0].tms_utime); /* Decoding */ #ifdef USE_AV_DECODER times(&tmp_time[0]); avcodec_decode_video(av_decoder_ctx, picture_ptr, &dummy, dv_buffer, sizeof(dv_buffer)); times(&tmp_time[1]); av_time_dec += (tmp_time[1].tms_utime - tmp_time[0].tms_utime); img_convert((AVPicture *)picture422, PIX_FMT_YUV422, (AVPicture *)picture411, PIX_FMT_YUV411P, RAW_FRAME_W, RAW_FRAME_H); AV_MSE[i] = AV_MSE[i] + (long double)frame_mse(original_frame, picture422->data[0])/RAW_FRAME_SIZE; #else pixels[0] = test_frame; memset(test_frame, 0, sizeof(test_frame)); dv_parse_header(dv_decoder, dv_buffer); dv_decode_full_frame(dv_decoder, dv_buffer, e_dv_color_yuv, pixels, pitches); AV_MSE[i] = AV_MSE[i] + (long double)frame_mse(original_frame, test_frame)/RAW_FRAME_SIZE; #endif } } printf("%4s|%10s|%10s|%10s|%10s\n", "iter", "libdv mse", "libdv PSNR", "avlib mse", "avlib PSNR"); for (i=0; i<iter; i++) { AV_MSE[i] = AV_MSE[i] / total_frames; DV_MSE[i] = DV_MSE[i] / total_frames; printf("%4d|%10f|%10f|%10f|%10f\n", i, (float)DV_MSE[i], PSNR(DV_MSE[i]), (float)AV_MSE[i], PSNR(AV_MSE[i])); } printf("\n%10s|%10s|%10s|%10s\n", "libdv enc", "libdv dec", "avlib enc", "avlib dec"); printf("%10d|%10d|%10d|%10d\n", dv_time_enc, dv_time_dec, av_time_enc, av_time_dec); return 0; } |