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 ****************************************************************************/