Mercurial > mplayer.hg
comparison libmpcodecs/ve_xvid4.c @ 13610:b79ee5bf2c9e
Sync with GomGom's patch-12 version.
updated copyright
bvhq options added (xvid 1.1+ api4.1)
psnr handling moved in separate functions
proper free() on uninit
printf -> mp_msg
capability to flush delayed frames
Changes by me (iive)
support for flushing delayed frames at the end
suppressed cosmetics and new aspect code changes
author | iive |
---|---|
date | Mon, 11 Oct 2004 15:48:18 +0000 |
parents | 2a02e3dc8ba3 |
children | d4cba4c4c54c |
comparison
equal
deleted
inserted
replaced
13609:529aad3fc0a4 | 13610:b79ee5bf2c9e |
---|---|
1 /***************************************************************************** | 1 /***************************************************************************** |
2 * | 2 * |
3 * - XviD 1.0 export module for mplayer/mencoder - | 3 * - XviD 1.x export module for mplayer/mencoder - |
4 * | 4 * |
5 * Copyright(C) 2003 Marco Belli <elcabesa@inwind.it> | 5 * Copyright(C) 2003 Marco Belli <elcabesa@inwind.it> |
6 * 2003 Edouard Gomez <ed.gomez@free.fr> | 6 * 2003-2004 Edouard Gomez <ed.gomez@free.fr> |
7 * | 7 * |
8 * This program is free software; you can redistribute it and/or modify | 8 * This program is free software; you can redistribute it and/or modify |
9 * it under the terms of the GNU General Public License as published by | 9 * it under the terms of the GNU General Public License as published by |
10 * the Free Software Foundation; either version 2 of the License, or | 10 * the Free Software Foundation; either version 2 of the License, or |
11 * (at your option) any later version. | 11 * (at your option) any later version. |
61 #define FINE (!0) | 61 #define FINE (!0) |
62 #define BAD (!FINE) | 62 #define BAD (!FINE) |
63 | 63 |
64 // Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation | 64 // Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation |
65 | 65 |
66 typedef struct XVIDRational{ | 66 typedef struct xvid_rational_s{ |
67 int num; | 67 int num; |
68 int den; | 68 int den; |
69 } XVIDRational; | 69 } XVIDRational; |
70 | 70 |
71 #define MAX(a,b) ((a) > (b) ? (a) : (b)) | 71 #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
158 static int xvidenc_cartoon = 0; | 158 static int xvidenc_cartoon = 0; |
159 static int xvidenc_hqacpred = 1; | 159 static int xvidenc_hqacpred = 1; |
160 static int xvidenc_chromame = 0; | 160 static int xvidenc_chromame = 0; |
161 static int xvidenc_chroma_opt = 0; | 161 static int xvidenc_chroma_opt = 0; |
162 static int xvidenc_vhq = 0; | 162 static int xvidenc_vhq = 0; |
163 static int xvidenc_bvhq = 0; | |
163 static int xvidenc_motion = 6; | 164 static int xvidenc_motion = 6; |
164 static int xvidenc_turbo = 0; | 165 static int xvidenc_turbo = 0; |
165 static int xvidenc_stats = 0; | 166 static int xvidenc_stats = 0; |
166 static int xvidenc_max_key_interval = 0; /* Let xvidcore set a 10s interval by default */ | 167 static int xvidenc_max_key_interval = 0; /* Let xvidcore set a 10s interval by default */ |
167 static int xvidenc_frame_drop_ratio = 0; | 168 static int xvidenc_frame_drop_ratio = 0; |
211 {"quant_type", &xvidenc_quant_method, CONF_TYPE_STRING, 0, 0, 0, NULL}, | 212 {"quant_type", &xvidenc_quant_method, CONF_TYPE_STRING, 0, 0, 0, NULL}, |
212 {"me_quality", &xvidenc_motion, CONF_TYPE_INT, CONF_RANGE, 0, 6, NULL}, | 213 {"me_quality", &xvidenc_motion, CONF_TYPE_INT, CONF_RANGE, 0, 6, NULL}, |
213 {"chroma_me", &xvidenc_chromame, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | 214 {"chroma_me", &xvidenc_chromame, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
214 {"chroma_opt", &xvidenc_chroma_opt, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | 215 {"chroma_opt", &xvidenc_chroma_opt, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
215 {"vhq", &xvidenc_vhq, CONF_TYPE_INT, CONF_RANGE, 0, 4, NULL}, | 216 {"vhq", &xvidenc_vhq, CONF_TYPE_INT, CONF_RANGE, 0, 4, NULL}, |
217 {"bvhq", &xvidenc_bvhq, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL}, | |
216 {"max_bframes", &xvidenc_max_bframes, CONF_TYPE_INT, CONF_RANGE, 0, 20, NULL}, | 218 {"max_bframes", &xvidenc_max_bframes, CONF_TYPE_INT, CONF_RANGE, 0, 20, NULL}, |
217 {"bquant_ratio", &xvidenc_bquant_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL}, | 219 {"bquant_ratio", &xvidenc_bquant_ratio, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL}, |
218 {"bquant_offset", &xvidenc_bquant_offset, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL}, | 220 {"bquant_offset", &xvidenc_bquant_offset, CONF_TYPE_INT, CONF_RANGE, 0, 200, NULL}, |
219 {"bf_threshold", &xvidenc_bframe_threshold, CONF_TYPE_INT, CONF_RANGE, -255, 255, NULL}, | 221 {"bf_threshold", &xvidenc_bframe_threshold, CONF_TYPE_INT, CONF_RANGE, -255, 255, NULL}, |
220 {"qpel", &xvidenc_quarterpel, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | 222 {"qpel", &xvidenc_quarterpel, CONF_TYPE_FLAG, 0, 0, 1, NULL}, |
308 int max_sse_u; | 310 int max_sse_u; |
309 int max_sse_v; | 311 int max_sse_v; |
310 int max_framenum; | 312 int max_framenum; |
311 | 313 |
312 int pixels; | 314 int pixels; |
313 int d_width, d_height; | 315 |
316 /* DAR/PAR and all that thingies */ | |
317 int d_width; | |
318 int d_height; | |
319 FILE *fvstats; | |
314 } xvid_mplayer_module_t; | 320 } xvid_mplayer_module_t; |
315 | 321 |
316 static void dispatch_settings(xvid_mplayer_module_t *mod); | 322 static void dispatch_settings(xvid_mplayer_module_t *mod); |
317 static int set_create_struct(xvid_mplayer_module_t *mod); | 323 static int set_create_struct(xvid_mplayer_module_t *mod); |
318 static int set_frame_struct(xvid_mplayer_module_t *mod, mp_image_t *mpi); | 324 static int set_frame_struct(xvid_mplayer_module_t *mod, mp_image_t *mpi); |
325 static void update_stats(xvid_mplayer_module_t *mod, xvid_enc_stats_t *stats); | |
326 static void print_stats(xvid_mplayer_module_t *mod); | |
327 static void flush_internal_buffers(xvid_mplayer_module_t *mod); | |
328 static const char *par_string(int parcode); | |
319 static const char *errorstring(int err); | 329 static const char *errorstring(int err); |
320 | 330 |
321 /***************************************************************************** | 331 /***************************************************************************** |
322 * Video Filter API function definitions | 332 * Video Filter API function definitions |
323 ****************************************************************************/ | 333 ****************************************************************************/ |
336 | 346 |
337 /* Complete the muxer initialization */ | 347 /* Complete the muxer initialization */ |
338 mod->mux->bih->biWidth = width; | 348 mod->mux->bih->biWidth = width; |
339 mod->mux->bih->biHeight = height; | 349 mod->mux->bih->biHeight = height; |
340 mod->mux->bih->biSizeImage = | 350 mod->mux->bih->biSizeImage = |
341 mod->mux->bih->biWidth * mod->mux->bih->biHeight * 3; | 351 mod->mux->bih->biWidth * mod->mux->bih->biHeight * 3 / 2; |
342 mod->mux->aspect = (float)d_width/d_height; | 352 mod->mux->aspect = (float)d_width/d_height; |
343 | 353 |
344 /* Message the FourCC type */ | 354 /* Message the FourCC type */ |
345 mp_msg(MSGT_MENCODER, MSGL_INFO, | 355 mp_msg(MSGT_MENCODER, MSGL_INFO, |
346 "videocodec: XviD (%dx%d fourcc=%x [%.4s])\n", | 356 "videocodec: XviD (%dx%d fourcc=%x [%.4s])\n", |
347 width, height, mod->mux->bih->biCompression, | 357 width, height, mod->mux->bih->biCompression, |
348 (char *)&mod->mux->bih->biCompression); | 358 (char *)&mod->mux->bih->biCompression); |
349 | 359 |
360 /* Total number of pixels per frame required for PSNR */ | |
361 mod->pixels = mod->mux->bih->biWidth*mod->mux->bih->biHeight; | |
362 | |
350 /*-------------------------------------------------------------------- | 363 /*-------------------------------------------------------------------- |
351 * Dispatch all module settings to XviD structures | 364 * Dispatch all module settings to XviD structures |
352 *------------------------------------------------------------------*/ | 365 *------------------------------------------------------------------*/ |
353 | 366 |
354 mod->d_width = d_width; | 367 mod->d_width = d_width; |
392 xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv; | 405 xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv; |
393 | 406 |
394 /* Destroy xvid instance */ | 407 /* Destroy xvid instance */ |
395 xvid_encore(mod->instance, XVID_ENC_DESTROY, NULL, NULL); | 408 xvid_encore(mod->instance, XVID_ENC_DESTROY, NULL, NULL); |
396 | 409 |
397 /* Display stats */ | 410 /* Display stats (if any) */ |
398 if(mod->frames) { | 411 print_stats(mod); |
399 mod->sse_y /= mod->frames; | 412 |
400 mod->sse_u /= mod->frames; | 413 /* Close PSNR file if ever opened */ |
401 mod->sse_v /= mod->frames; | 414 if (mod->fvstats) { |
402 | 415 fclose(mod->fvstats); |
403 #define SSE2PSNR(sse, nbpixels) \ | 416 mod->fvstats = NULL; |
404 ((!(sse)) ? 99.99f : 48.131f - 10*(double)log10((double)(sse)/(double)((nbpixels)))) | 417 } |
405 mp_msg(MSGT_MENCODER, MSGL_INFO, | 418 |
406 "The value 99.99dB is a special value and represents " | 419 /* Free allocated memory */ |
407 "the upper range limit\n"); | 420 if(mod->frame.quant_intra_matrix) |
408 mp_msg(MSGT_MENCODER, MSGL_INFO, | 421 free(mod->frame.quant_intra_matrix); |
409 "xvid: Min PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, in frame %d\n", | 422 |
410 SSE2PSNR(mod->max_sse_y, mod->pixels), | 423 if(mod->frame.quant_inter_matrix) |
411 SSE2PSNR(mod->max_sse_u, mod->pixels/4), | 424 free(mod->frame.quant_inter_matrix); |
412 SSE2PSNR(mod->max_sse_v, mod->pixels/4), | 425 |
413 mod->max_framenum); | 426 if(mod->mux->bih) |
414 mp_msg(MSGT_MENCODER, MSGL_INFO, | 427 free(mod->mux->bih); |
415 "xvid: Average PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, for %d frames\n", | 428 |
416 SSE2PSNR(mod->sse_y, mod->pixels), | 429 free(vf->priv); |
417 SSE2PSNR(mod->sse_u, mod->pixels/4), | 430 vf->priv=NULL; |
418 SSE2PSNR(mod->sse_v, mod->pixels/4), | |
419 mod->frames); | |
420 mp_msg(MSGT_MENCODER, MSGL_INFO, | |
421 "xvid: Max PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, in frame %d\n", | |
422 SSE2PSNR(mod->min_sse_y, mod->pixels), | |
423 SSE2PSNR(mod->min_sse_u, mod->pixels/4), | |
424 SSE2PSNR(mod->min_sse_v, mod->pixels/4), | |
425 mod->min_framenum); | |
426 } | |
427 | |
428 /* ToDo: free matrices, and some string settings (quant method, matrix | |
429 * filenames...) */ | |
430 | 431 |
431 return; | 432 return; |
432 } | 433 } |
433 | 434 |
434 /*============================================================================ | 435 /*============================================================================ |
436 *==========================================================================*/ | 437 *==========================================================================*/ |
437 | 438 |
438 static int | 439 static int |
439 control(struct vf_instance_s* vf, int request, void* data) | 440 control(struct vf_instance_s* vf, int request, void* data) |
440 { | 441 { |
442 xvid_mplayer_module_t *mod = (xvid_mplayer_module_t *)vf->priv; | |
443 | |
444 switch(request){ | |
445 case VFCTRL_FLUSH_FRAMES: | |
446 if(mod)/*paranoid*/ | |
447 flush_internal_buffers(mod); | |
448 break; | |
449 } | |
441 return(CONTROL_UNKNOWN); | 450 return(CONTROL_UNKNOWN); |
442 } | 451 } |
443 | 452 |
444 /*============================================================================ | 453 /*============================================================================ |
445 * query_format | 454 * query_format |
498 } | 507 } |
499 | 508 |
500 /* If size is == 0, we're done with that frame */ | 509 /* If size is == 0, we're done with that frame */ |
501 if(size == 0) return(FINE); | 510 if(size == 0) return(FINE); |
502 | 511 |
503 /* Did xvidcore returned stats about an encoded frame ? (asynchronous) */ | 512 /* xvidcore returns stats about encoded frame in an asynchronous way |
504 if(xvidenc_stats && stats.type > 0) { | 513 * accumulate these stats */ |
505 mod->sse_y += stats.sse_y; | 514 update_stats(mod, &stats); |
506 mod->sse_u += stats.sse_u; | |
507 mod->sse_v += stats.sse_v; | |
508 | |
509 if(mod->min_sse_y > stats.sse_y) { | |
510 mod->min_sse_y = stats.sse_y; | |
511 mod->min_sse_u = stats.sse_u; | |
512 mod->min_sse_v = stats.sse_v; | |
513 mod->min_framenum = mod->frames; | |
514 } | |
515 | |
516 if(mod->max_sse_y < stats.sse_y) { | |
517 mod->max_sse_y = stats.sse_y; | |
518 mod->max_sse_u = stats.sse_u; | |
519 mod->max_sse_v = stats.sse_v; | |
520 mod->max_framenum = mod->frames; | |
521 } | |
522 if (xvidenc_psnr) { | |
523 static FILE *fvstats = NULL; | |
524 char filename[20]; | |
525 | |
526 if (!fvstats) { | |
527 time_t today2; | |
528 struct tm *today; | |
529 today2 = time (NULL); | |
530 today = localtime (&today2); | |
531 sprintf (filename, "psnr_%02d%02d%02d.log", today->tm_hour, today->tm_min, today->tm_sec); | |
532 fvstats = fopen (filename,"w"); | |
533 if (!fvstats) { | |
534 perror ("fopen"); | |
535 xvidenc_psnr = 0; // disable block | |
536 } | |
537 } | |
538 fprintf (fvstats, "%6d, %2d, %6d, %2.2f, %2.2f, %2.2f, %2.2f %c\n", | |
539 mod->frames, | |
540 stats.quant, | |
541 stats.length, | |
542 SSE2PSNR (stats.sse_y, mod->pixels), | |
543 SSE2PSNR (stats.sse_u, mod->pixels / 4), | |
544 SSE2PSNR (stats.sse_v, mod->pixels / 4), | |
545 SSE2PSNR (stats.sse_y + stats.sse_u + stats.sse_v,(double)mod->pixels * 1.5), | |
546 stats.type==1?'I':stats.type==2?'P':stats.type==3?'B':stats.type?'S':'?' | |
547 ); | |
548 } | |
549 mod->frames++; | |
550 | |
551 } | |
552 #undef SSE2PSNR | |
553 | 515 |
554 /* xvidcore outputed bitstream -- mux it */ | 516 /* xvidcore outputed bitstream -- mux it */ |
555 muxer_write_chunk(mod->mux, | 517 muxer_write_chunk(mod->mux, |
556 size, | 518 size, |
557 (mod->frame.out_flags & XVID_KEYFRAME)?0x10:0); | 519 (mod->frame.out_flags & XVID_KEYFRAME)?0x10:0); |
606 | 568 |
607 mod->mux->bih->biSize = sizeof(BITMAPINFOHEADER); | 569 mod->mux->bih->biSize = sizeof(BITMAPINFOHEADER); |
608 mod->mux->bih->biWidth = 0; | 570 mod->mux->bih->biWidth = 0; |
609 mod->mux->bih->biHeight = 0; | 571 mod->mux->bih->biHeight = 0; |
610 mod->mux->bih->biPlanes = 1; | 572 mod->mux->bih->biPlanes = 1; |
611 mod->mux->bih->biBitCount = 24; | 573 mod->mux->bih->biBitCount = 12; |
612 mod->mux->bih->biCompression = mmioFOURCC('X','V','I','D'); | 574 mod->mux->bih->biCompression = mmioFOURCC('X','V','I','D'); |
613 | 575 |
614 /* Retrieve information about the host XviD library */ | 576 /* Retrieve information about the host XviD library */ |
615 memset(&xvid_gbl_info, 0, sizeof(xvid_gbl_info_t)); | 577 memset(&xvid_gbl_info, 0, sizeof(xvid_gbl_info_t)); |
616 xvid_gbl_info.version = XVID_VERSION; | 578 xvid_gbl_info.version = XVID_VERSION; |
617 | 579 |
618 if (xvid_global(NULL, XVID_GBL_INFO, &xvid_gbl_info, NULL) < 0) { | 580 if (xvid_global(NULL, XVID_GBL_INFO, &xvid_gbl_info, NULL) < 0) { |
619 mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: could not get information about the library\n"); | 581 mp_msg(MSGT_MENCODER,MSGL_WARN, "xvid: could not get information about the library\n"); |
620 } else { | 582 } else { |
621 mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: using library version %d.%d.%d (build %s)\n", | 583 mp_msg(MSGT_MENCODER,MSGL_INFO, "xvid: using library version %d.%d.%d (build %s)\n", |
622 XVID_VERSION_MAJOR(xvid_gbl_info.actual_version), | 584 XVID_VERSION_MAJOR(xvid_gbl_info.actual_version), |
623 XVID_VERSION_MINOR(xvid_gbl_info.actual_version), | 585 XVID_VERSION_MINOR(xvid_gbl_info.actual_version), |
624 XVID_VERSION_PATCH(xvid_gbl_info.actual_version), | 586 XVID_VERSION_PATCH(xvid_gbl_info.actual_version), |
753 } | 715 } |
754 | 716 |
755 if(xvidenc_intra_matrix_file != NULL) { | 717 if(xvidenc_intra_matrix_file != NULL) { |
756 frame->quant_intra_matrix = (unsigned char*)read_matrix(xvidenc_intra_matrix_file); | 718 frame->quant_intra_matrix = (unsigned char*)read_matrix(xvidenc_intra_matrix_file); |
757 if(frame->quant_intra_matrix != NULL) { | 719 if(frame->quant_intra_matrix != NULL) { |
758 fprintf(stderr, "xvid: Loaded Intra matrix (switching to mpeg quantization type)\n"); | 720 mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: Loaded Intra matrix (switching to mpeg quantization type)\n"); |
759 if(xvidenc_quant_method) free(xvidenc_quant_method); | 721 if(xvidenc_quant_method) free(xvidenc_quant_method); |
760 xvidenc_quant_method = strdup("mpeg"); | 722 xvidenc_quant_method = strdup("mpeg"); |
761 } | 723 } |
762 } | 724 } |
763 if(xvidenc_inter_matrix_file != NULL) { | 725 if(xvidenc_inter_matrix_file != NULL) { |
764 frame->quant_inter_matrix = read_matrix(xvidenc_inter_matrix_file); | 726 frame->quant_inter_matrix = read_matrix(xvidenc_inter_matrix_file); |
765 if(frame->quant_inter_matrix) { | 727 if(frame->quant_inter_matrix) { |
766 fprintf(stderr, "\nxvid: Loaded Inter matrix (switching to mpeg quantization type)\n"); | 728 mp_msg(MSGT_MENCODER, MSGL_INFO, "\nxvid: Loaded Inter matrix (switching to mpeg quantization type)\n"); |
767 if(xvidenc_quant_method) free(xvidenc_quant_method); | 729 if(xvidenc_quant_method) free(xvidenc_quant_method); |
768 xvidenc_quant_method = strdup("mpeg"); | 730 xvidenc_quant_method = strdup("mpeg"); |
769 } | 731 } |
770 } | 732 } |
771 if(xvidenc_quant_method != NULL && !strcasecmp(xvidenc_quant_method, "mpeg")) { | 733 if(xvidenc_quant_method != NULL && !strcasecmp(xvidenc_quant_method, "mpeg")) { |
811 frame->motion |= XVID_ME_QUARTERPELREFINE8_RD; | 773 frame->motion |= XVID_ME_QUARTERPELREFINE8_RD; |
812 frame->motion |= XVID_ME_CHECKPREDICTION_RD; | 774 frame->motion |= XVID_ME_CHECKPREDICTION_RD; |
813 } | 775 } |
814 if(xvidenc_vhq >= 4) { | 776 if(xvidenc_vhq >= 4) { |
815 frame->motion |= XVID_ME_EXTSEARCH_RD; | 777 frame->motion |= XVID_ME_EXTSEARCH_RD; |
778 } | |
779 if(xvidenc_bvhq >= 1) { | |
780 #if XVID_API >= XVID_MAKE_API(4,1) | |
781 frame->vop_flags |= XVID_VOP_RD_BVOP; | |
782 #endif | |
816 } | 783 } |
817 if(xvidenc_turbo) { | 784 if(xvidenc_turbo) { |
818 frame->motion |= XVID_ME_FASTREFINE16; | 785 frame->motion |= XVID_ME_FASTREFINE16; |
819 frame->motion |= XVID_ME_FASTREFINE8; | 786 frame->motion |= XVID_ME_FASTREFINE8; |
820 frame->motion |= XVID_ME_SKIP_DELTASEARCH; | 787 frame->motion |= XVID_ME_SKIP_DELTASEARCH; |
855 frame->par = XVID_PAR_EXT; | 822 frame->par = XVID_PAR_EXT; |
856 frame->par_width = ar.num; | 823 frame->par_width = ar.num; |
857 frame->par_height= ar.den; | 824 frame->par_height= ar.den; |
858 } | 825 } |
859 | 826 |
860 mp_msg(MSGT_MENCODER, MSGL_INFO, "XVID4_DAR: %d/%d code %d, Display frame: (%d, %d), original frame: (%d, %d)\n", | |
861 ar.num, ar.den, frame->par, | |
862 mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight); | |
863 } else if(xvidenc_par != NULL) { | 827 } else if(xvidenc_par != NULL) { |
864 if(strcasecmp(xvidenc_par, "pal43") == 0) | 828 if(strcasecmp(xvidenc_par, "pal43") == 0) |
865 frame->par = XVID_PAR_43_PAL; | 829 frame->par = XVID_PAR_43_PAL; |
866 else if(strcasecmp(xvidenc_par, "pal169") == 0) | 830 else if(strcasecmp(xvidenc_par, "pal169") == 0) |
867 frame->par = XVID_PAR_169_PAL; | 831 frame->par = XVID_PAR_169_PAL; |
882 frame->par_height = xvidenc_par_height; | 846 frame->par_height = xvidenc_par_height; |
883 else | 847 else |
884 frame->par_height = 1; | 848 frame->par_height = 1; |
885 } | 849 } |
886 } | 850 } |
851 | |
852 /* Display par information */ | |
853 mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: par=%d/%d (%s), displayed=%dx%d, sampled=%dx%d\n", | |
854 ar.num, ar.den, par_string(frame->par), | |
855 mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight); | |
887 return; | 856 return; |
888 } | 857 } |
889 | 858 |
890 static int set_create_struct(xvid_mplayer_module_t *mod) | 859 static int set_create_struct(xvid_mplayer_module_t *mod) |
891 { | 860 { |
897 create->version = XVID_VERSION; | 866 create->version = XVID_VERSION; |
898 | 867 |
899 /* Width and Height */ | 868 /* Width and Height */ |
900 create->width = mod->mux->bih->biWidth; | 869 create->width = mod->mux->bih->biWidth; |
901 create->height = mod->mux->bih->biHeight; | 870 create->height = mod->mux->bih->biHeight; |
902 | |
903 /* Pixels are needed for PSNR calculations */ | |
904 mod->pixels = create->width * create->height; | |
905 | 871 |
906 /* FPS */ | 872 /* FPS */ |
907 create->fincr = mod->mux->h.dwScale; | 873 create->fincr = mod->mux->h.dwScale; |
908 create->fbase = mod->mux->h.dwRate; | 874 create->fbase = mod->mux->h.dwRate; |
909 | 875 |
928 " with other Rate Control mechanisms\n"); | 894 " with other Rate Control mechanisms\n"); |
929 return(BAD); | 895 return(BAD); |
930 } | 896 } |
931 | 897 |
932 if(xvidenc_bitrate != 0 && xvidenc_pass == 1) { | 898 if(xvidenc_bitrate != 0 && xvidenc_pass == 1) { |
933 mp_msg(MSGT_MENCODER, MSGL_ERR, | 899 mp_msg(MSGT_MENCODER, MSGL_WARN, |
934 "xvid: bitrate setting is ignored during first pass\n"); | 900 "xvid: bitrate setting is ignored during first pass\n"); |
935 } | 901 } |
936 | 902 |
937 /* Sort out which sort of pass we are supposed to do | 903 /* Sort out which sort of pass we are supposed to do |
938 * pass == 1<<0 CBR | 904 * pass == 1<<0 CBR |
1105 frame->quant = 0; | 1071 frame->quant = 0; |
1106 | 1072 |
1107 return(FINE); | 1073 return(FINE); |
1108 } | 1074 } |
1109 | 1075 |
1076 static void | |
1077 flush_internal_buffers(xvid_mplayer_module_t *mod) | |
1078 { | |
1079 int size; | |
1080 xvid_enc_frame_t *frame = &mod->frame; | |
1081 | |
1082 if (mod->instance == NULL) | |
1083 return;/*encoder not inited*/ | |
1084 | |
1085 /* Init a fake frame to force flushing */ | |
1086 frame->version = XVID_VERSION; | |
1087 frame->bitstream = mod->mux->buffer; | |
1088 frame->length = -1; | |
1089 frame->input.csp = XVID_CSP_NULL; | |
1090 frame->input.plane[0] = NULL; | |
1091 frame->input.plane[1] = NULL; | |
1092 frame->input.plane[2] = NULL; | |
1093 frame->input.stride[0] = 0; | |
1094 frame->input.stride[1] = 0; | |
1095 frame->input.stride[2] = 0; | |
1096 frame->quant = 0; | |
1097 | |
1098 /* Flush encoder buffers caused by bframes usage */ | |
1099 do { | |
1100 xvid_enc_stats_t stats; | |
1101 memset(&stats, 0, sizeof(xvid_enc_stats_t)); | |
1102 stats.version = XVID_VERSION; | |
1103 | |
1104 /* Encode internal buffer */ | |
1105 size = xvid_encore(mod->instance, XVID_ENC_ENCODE, &mod->frame, &stats); | |
1106 | |
1107 if (size>0) { | |
1108 /* Update stats */ | |
1109 update_stats(mod, &stats); | |
1110 | |
1111 /* xvidcore outputed bitstream -- mux it */ | |
1112 muxer_write_chunk(mod->mux, size, | |
1113 (mod->frame.out_flags & XVID_KEYFRAME)?0x10:0); | |
1114 } | |
1115 } while (size>0); | |
1116 } | |
1117 | |
1118 #define SSE2PSNR(sse, nbpixels) \ | |
1119 ((!(sse)) ? 99.99f : 48.131f - 10*(double)log10((double)(sse)/(double)((nbpixels)))) | |
1120 static void | |
1121 update_stats(xvid_mplayer_module_t *mod, xvid_enc_stats_t *stats) | |
1122 { | |
1123 if(xvidenc_stats && stats->type > 0) { | |
1124 mod->sse_y += stats->sse_y; | |
1125 mod->sse_u += stats->sse_u; | |
1126 mod->sse_v += stats->sse_v; | |
1127 | |
1128 if(mod->min_sse_y > stats->sse_y) { | |
1129 mod->min_sse_y = stats->sse_y; | |
1130 mod->min_sse_u = stats->sse_u; | |
1131 mod->min_sse_v = stats->sse_v; | |
1132 mod->min_framenum = mod->frames; | |
1133 } | |
1134 | |
1135 if(mod->max_sse_y < stats->sse_y) { | |
1136 mod->max_sse_y = stats->sse_y; | |
1137 mod->max_sse_u = stats->sse_u; | |
1138 mod->max_sse_v = stats->sse_v; | |
1139 mod->max_framenum = mod->frames; | |
1140 } | |
1141 | |
1142 if (xvidenc_psnr) { | |
1143 if (!mod->fvstats) { | |
1144 char filename[20]; | |
1145 time_t today2; | |
1146 struct tm *today; | |
1147 today2 = time (NULL); | |
1148 today = localtime (&today2); | |
1149 sprintf (filename, "psnr_%02d%02d%02d.log", today->tm_hour, today->tm_min, today->tm_sec); | |
1150 mod->fvstats = fopen (filename,"w"); | |
1151 if (!mod->fvstats) { | |
1152 perror ("fopen"); | |
1153 /* Disable PSNR file output so we don't get here again */ | |
1154 xvidenc_psnr = 0; | |
1155 } | |
1156 } | |
1157 fprintf (mod->fvstats, "%6d, %2d, %6d, %2.2f, %2.2f, %2.2f, %2.2f %c\n", | |
1158 mod->frames, | |
1159 stats->quant, | |
1160 stats->length, | |
1161 SSE2PSNR (stats->sse_y, mod->pixels), | |
1162 SSE2PSNR (stats->sse_u, mod->pixels / 4), | |
1163 SSE2PSNR (stats->sse_v, mod->pixels / 4), | |
1164 SSE2PSNR (stats->sse_y + stats->sse_u + stats->sse_v,(double)mod->pixels * 1.5), | |
1165 stats->type==1?'I':stats->type==2?'P':stats->type==3?'B':stats->type?'S':'?' | |
1166 ); | |
1167 } | |
1168 mod->frames++; | |
1169 } | |
1170 } | |
1171 | |
1172 static void | |
1173 print_stats(xvid_mplayer_module_t *mod) | |
1174 { | |
1175 if (mod->frames) { | |
1176 mod->sse_y /= mod->frames; | |
1177 mod->sse_u /= mod->frames; | |
1178 mod->sse_v /= mod->frames; | |
1179 | |
1180 mp_msg(MSGT_MENCODER, MSGL_INFO, | |
1181 "The value 99.99dB is a special value and represents " | |
1182 "the upper range limit\n"); | |
1183 mp_msg(MSGT_MENCODER, MSGL_INFO, | |
1184 "xvid: Min PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, in frame %d\n", | |
1185 SSE2PSNR(mod->max_sse_y, mod->pixels), | |
1186 SSE2PSNR(mod->max_sse_u, mod->pixels/4), | |
1187 SSE2PSNR(mod->max_sse_v, mod->pixels/4), | |
1188 mod->max_framenum); | |
1189 mp_msg(MSGT_MENCODER, MSGL_INFO, | |
1190 "xvid: Average PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, for %d frames\n", | |
1191 SSE2PSNR(mod->sse_y, mod->pixels), | |
1192 SSE2PSNR(mod->sse_u, mod->pixels/4), | |
1193 SSE2PSNR(mod->sse_v, mod->pixels/4), | |
1194 mod->frames); | |
1195 mp_msg(MSGT_MENCODER, MSGL_INFO, | |
1196 "xvid: Max PSNR y : %.2f dB, u : %.2f dB, v : %.2f dB, in frame %d\n", | |
1197 SSE2PSNR(mod->min_sse_y, mod->pixels), | |
1198 SSE2PSNR(mod->min_sse_u, mod->pixels/4), | |
1199 SSE2PSNR(mod->min_sse_v, mod->pixels/4), | |
1200 mod->min_framenum); | |
1201 } | |
1202 } | |
1203 #undef SSE2PSNR | |
1204 | |
1110 static void *read_matrix(unsigned char *filename) | 1205 static void *read_matrix(unsigned char *filename) |
1111 { | 1206 { |
1112 int i; | 1207 int i; |
1113 unsigned char *matrix; | 1208 unsigned char *matrix; |
1114 FILE *input; | 1209 FILE *input; |
1117 if((matrix = malloc(64*sizeof(unsigned char))) == NULL) | 1212 if((matrix = malloc(64*sizeof(unsigned char))) == NULL) |
1118 return(NULL); | 1213 return(NULL); |
1119 | 1214 |
1120 /* Open the matrix file */ | 1215 /* Open the matrix file */ |
1121 if((input = fopen(filename, "rb")) == NULL) { | 1216 if((input = fopen(filename, "rb")) == NULL) { |
1122 fprintf(stderr, | 1217 mp_msg(MSGT_MENCODER, MSGL_ERR, |
1123 "xvid: Error opening the matrix file %s\n", | 1218 "xvid: Error opening the matrix file %s\n", |
1124 filename); | 1219 filename); |
1125 free(matrix); | 1220 free(matrix); |
1126 return(NULL); | 1221 return(NULL); |
1127 } | 1222 } |
1131 | 1226 |
1132 int value; | 1227 int value; |
1133 | 1228 |
1134 /* If fscanf fails then get out of the loop */ | 1229 /* If fscanf fails then get out of the loop */ |
1135 if(fscanf(input, "%d", &value) != 1) { | 1230 if(fscanf(input, "%d", &value) != 1) { |
1136 fprintf(stderr, | 1231 mp_msg(MSGT_MENCODER, MSGL_ERR, |
1137 "xvid: Error reading the matrix file %s\n", | 1232 "xvid: Error reading the matrix file %s\n", |
1138 filename); | 1233 filename); |
1139 free(matrix); | 1234 free(matrix); |
1140 fclose(input); | 1235 fclose(input); |
1141 return(NULL); | 1236 return(NULL); |
1155 | 1250 |
1156 return(matrix); | 1251 return(matrix); |
1157 | 1252 |
1158 } | 1253 } |
1159 | 1254 |
1255 | |
1256 static const char * | |
1257 par_string(int parcode) | |
1258 { | |
1259 const char *par_string; | |
1260 switch (parcode) { | |
1261 case XVID_PAR_11_VGA: | |
1262 par_string = "vga11"; | |
1263 break; | |
1264 case XVID_PAR_43_PAL: | |
1265 par_string = "pal43"; | |
1266 break; | |
1267 case XVID_PAR_43_NTSC: | |
1268 par_string = "ntsc43"; | |
1269 break; | |
1270 case XVID_PAR_169_PAL: | |
1271 par_string = "pal169"; | |
1272 break; | |
1273 case XVID_PAR_169_NTSC: | |
1274 par_string = "ntsc69"; | |
1275 break; | |
1276 case XVID_PAR_EXT: | |
1277 par_string = "ext"; | |
1278 break; | |
1279 default: | |
1280 par_string = "unknown"; | |
1281 break; | |
1282 } | |
1283 return (par_string); | |
1284 } | |
1285 | |
1160 static const char *errorstring(int err) | 1286 static const char *errorstring(int err) |
1161 { | 1287 { |
1162 char *error; | 1288 const char *error; |
1163 switch(err) { | 1289 switch(err) { |
1164 case XVID_ERR_FAIL: | 1290 case XVID_ERR_FAIL: |
1165 error = "General fault"; | 1291 error = "General fault"; |
1166 break; | 1292 break; |
1167 case XVID_ERR_MEMORY: | 1293 case XVID_ERR_MEMORY: |
1178 break; | 1304 break; |
1179 default: | 1305 default: |
1180 error = "Unknown"; | 1306 error = "Unknown"; |
1181 } | 1307 } |
1182 | 1308 |
1183 return((const char *)error); | 1309 return(error); |
1184 } | 1310 } |
1185 | 1311 |
1186 /***************************************************************************** | 1312 /***************************************************************************** |
1187 * Module structure definition | 1313 * Module structure definition |
1188 ****************************************************************************/ | 1314 ****************************************************************************/ |