comparison libmpcodecs/ve_xvid4.c @ 16481:beebfccc00f1

adds Simple, Advanced Simple and DivX profile support for XviD, Patch by Robert Swain < robert POUM swain AH gmail POUM com > Nice help from Diego Biurrun, Reimar Dffinger, Guillaume POIRIER Original thread: Date: Sep 10, 2005 8:45 PM Subject: [MPlayer-dev-eng] [PATCH] XviD profile support
author gpoirier
date Tue, 13 Sep 2005 21:04:44 +0000
parents aa24bbbfd5c4
children 1218c5859ce8
comparison
equal deleted inserted replaced
16480:1ff9f67fd688 16481:beebfccc00f1
61 #define FINE (!0) 61 #define FINE (!0)
62 #define BAD (!FINE) 62 #define BAD (!FINE)
63 63
64 #define MAX_ZONES 64 64 #define MAX_ZONES 64
65 65
66 // Profile flag definitions
67 #define PROFILE_ADAPTQUANT 0x00000001
68 #define PROFILE_BVOP 0x00000002
69 #define PROFILE_MPEGQUANT 0x00000004
70 #define PROFILE_INTERLACE 0x00000008
71 #define PROFILE_QPEL 0x00000010
72 #define PROFILE_GMC 0x00000020
73 #define PROFILE_4MV 0x00000040
74 #define PROFILE_DXN 0x00000080
75
76 // Reduce code duplication in profiles[] array
77 #define PROFILE_S (PROFILE_4MV)
78 #define PROFILE_AS (PROFILE_4MV|PROFILE_ADAPTQUANT|PROFILE_BVOP|PROFILE_MPEGQUANT|PROFILE_INTERLACE|PROFILE_QPEL|PROFILE_GMC)
79
80 typedef struct
81 {
82 char *name; ///< profile name
83 int id; ///< mpeg-4 profile id; iso/iec 14496-2:2001 table G-1
84 int width; ///< profile width restriction
85 int height; ///< profile height restriction
86 int fps; ///< profile frame rate restriction
87 int max_objects; ///< ??????
88 int total_vmv_buffer_sz; ///< macroblock memory; when BVOPS=false, vmv = 2*vcv; when BVOPS=true, vmv = 3*vcv
89 int max_vmv_buffer_sz; ///< max macroblocks per vop
90 int vcv_decoder_rate; ///< macroblocks decoded per second
91 int max_acpred_mbs; ///< percentage
92 int max_vbv_size; ///< max vbv size (bits) 16368 bits
93 int max_video_packet_length; ///< bits
94 int max_bitrate; ///< bits per second
95 int vbv_peakrate; ///< max bits over anyone second period; 0=don't care
96 int dxn_max_bframes; ///< dxn: max consecutive bframes
97 unsigned int flags; ///< flags for allowed options/dxn note the definitions for PROFILE_S and PROFILE_AS
98 } profile_t;
99
66 // Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation 100 // Code taken from Libavcodec and ve_lavc.c to handle Aspect Ratio calculation
67 101
68 typedef struct xvid_rational_s{ 102 typedef struct xvid_rational_s{
69 int num; 103 int num;
70 int den; 104 int den;
139 xvid_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max); 173 xvid_reduce(&a.num, &a.den, (int64_t)(d * den + 0.5), den, max);
140 174
141 return a; 175 return a;
142 } 176 }
143 177
144 178 // Code taken from XviD VfW source for profile support
179
180 /* default vbv_occupancy is (64/170)*vbv_buffer_size */
181
182 const profile_t profiles[] =
183 {
184 /* name p@l w h fps obj Tvmv vmv vcv ac% vbv pkt bps vbv_peak dbf flags */
185 /* unrestricted profile (default) */
186 { "unrestricted", 0x00, 0, 0, 0, 0, 0, 0, 0, 100, 0*16368, -1, 0, 0, -1, 0xffffffff & ~PROFILE_DXN },
187
188 { "sp0", 0x08, 176, 144, 15, 1, 198, 99, 1485, 100, 10*16368, 2048, 64000, 0, -1, PROFILE_S },
189 /* simple@l0: max f_code=1, intra_dc_vlc_threshold=0 */
190 /* if ac preidition is used, adaptive quantization must not be used */
191 /* <=qcif must be used */
192 { "sp1", 0x01, 176, 144, 15, 4, 198, 99, 1485, 100, 10*16368, 2048, 64000, 0, -1, PROFILE_S|PROFILE_ADAPTQUANT },
193 { "sp2", 0x02, 352, 288, 15, 4, 792, 396, 5940, 100, 40*16368, 4096, 128000, 0, -1, PROFILE_S|PROFILE_ADAPTQUANT },
194 { "sp3", 0x03, 352, 288, 15, 4, 792, 396, 11880, 100, 40*16368, 8192, 384000, 0, -1, PROFILE_S|PROFILE_ADAPTQUANT },
195
196 { "asp0", 0xf0, 176, 144, 30, 1, 297, 99, 2970, 100, 10*16368, 2048, 128000, 0, -1, PROFILE_AS },
197 { "asp1", 0xf1, 176, 144, 30, 4, 297, 99, 2970, 100, 10*16368, 2048, 128000, 0, -1, PROFILE_AS },
198 { "asp2", 0xf2, 352, 288, 15, 4, 1188, 396, 5940, 100, 40*16368, 4096, 384000, 0, -1, PROFILE_AS },
199 { "asp3", 0xf3, 352, 288, 30, 4, 1188, 396, 11880, 100, 40*16368, 4096, 768000, 0, -1, PROFILE_AS },
200 /* ISMA Profile 1, (ASP) @ L3b (CIF, 1.5 Mb/s) CIF(352x288), 30fps, 1.5Mbps max ??? */
201 { "asp4", 0xf4, 352, 576, 30, 4, 2376, 792, 23760, 50, 80*16368, 8192, 3000000, 0, -1, PROFILE_AS },
202 { "asp5", 0xf5, 720, 576, 30, 4, 4860, 1620, 48600, 25, 112*16368, 16384, 8000000, 0, -1, PROFILE_AS },
203
204 // information provided by DivXNetworks, USA.
205 // "DivX Certified Profile Compatibility v1.1", February 2005
206 { "dxnhandheld", 0x00, 176, 144, 15, 1, 198, 99, 1485, 100, 32*8192, -1, 537600, 800000, 0, PROFILE_ADAPTQUANT|PROFILE_DXN },
207 { "dxnportntsc", 0x00, 352, 240, 30, 1, 990, 330, 36000, 100, 384*8192, -1, 4854000, 8000000, 1, PROFILE_4MV|PROFILE_ADAPTQUANT|PROFILE_BVOP|PROFILE_DXN },
208 { "dxnportpal", 0x00, 352, 288, 25, 1, 1188, 396, 36000, 100, 384*8192, -1, 4854000, 8000000, 1, PROFILE_4MV|PROFILE_ADAPTQUANT|PROFILE_BVOP|PROFILE_DXN },
209 { "dxnhtntsc", 0x00, 720, 480, 30, 1, 4050, 1350, 40500, 100, 384*8192, -1, 4854000, 8000000, 1, PROFILE_4MV|PROFILE_ADAPTQUANT|PROFILE_BVOP|PROFILE_INTERLACE|PROFILE_DXN },
210 { "dxnhtpal", 0x00, 720, 576, 25, 1, 4860, 1620, 40500, 100, 384*8192, -1, 4854000, 8000000, 1, PROFILE_4MV|PROFILE_ADAPTQUANT|PROFILE_BVOP|PROFILE_INTERLACE|PROFILE_DXN },
211 { "dxnhdtv", 0x00, 1280, 720, 30, 1,10800, 3600, 108000, 100, 768*8192, -1, 9708400, 16000000, 2, PROFILE_4MV|PROFILE_ADAPTQUANT|PROFILE_BVOP|PROFILE_INTERLACE|PROFILE_DXN },
212
213 { NULL, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00000000 },
214 };
215
216 /**
217 * \brief return the pointer to a chosen profile
218 * \param str the profile name
219 * \return pointer of the appropriate profiles array entry or NULL for a mistyped profile name
220 */
221 static profile_t *profileFromName(char *str)
222 {
223 profile_t *cur = profiles;
224 while (cur->name && strcasecmp(cur->name, str)) cur++;
225 if(!cur->name) return NULL;
226 return cur;
227 }
145 228
146 /***************************************************************************** 229 /*****************************************************************************
147 * Configuration options 230 * Configuration options
148 ****************************************************************************/ 231 ****************************************************************************/
149 232
195 static int xvidenc_vbr_max_overflow_improvement = 5; 278 static int xvidenc_vbr_max_overflow_improvement = 5;
196 static int xvidenc_vbr_max_overflow_degradation = 5; 279 static int xvidenc_vbr_max_overflow_degradation = 5;
197 static int xvidenc_vbr_kfreduction = 0; 280 static int xvidenc_vbr_kfreduction = 0;
198 static int xvidenc_vbr_kfthreshold = 0; 281 static int xvidenc_vbr_kfthreshold = 0;
199 static int xvidenc_vbr_container_frame_overhead = 24; /* mencoder uses AVI container */ 282 static int xvidenc_vbr_container_frame_overhead = 24; /* mencoder uses AVI container */
283
284 // commandline profile option string - default to unrestricted
285 static char *xvidenc_profile = "unrestricted";
200 286
201 static char *xvidenc_par = NULL; 287 static char *xvidenc_par = NULL;
202 static int xvidenc_par_width = 0; 288 static int xvidenc_par_width = 0;
203 static int xvidenc_par_height = 0; 289 static int xvidenc_par_height = 0;
204 static float xvidenc_dar_aspect = 0.0f; 290 static float xvidenc_dar_aspect = 0.0f;
289 {"noautoaspect", &xvidenc_autoaspect, CONF_TYPE_FLAG, 0, 1, 0, NULL}, 375 {"noautoaspect", &xvidenc_autoaspect, CONF_TYPE_FLAG, 0, 1, 0, NULL},
290 376
291 /* Section Zones */ 377 /* Section Zones */
292 {"zones", &xvidenc_zones, CONF_TYPE_STRING, 0, 0, 0, NULL}, 378 {"zones", &xvidenc_zones, CONF_TYPE_STRING, 0, 0, 0, NULL},
293 379
380 /* section profiles */
381 {"profile", &xvidenc_profile, CONF_TYPE_STRING, 0, 0, 0, NULL},
382
294 /* End of the config array */ 383 /* End of the config array */
295 {NULL, 0, 0, 0, 0, 0, NULL} 384 {NULL, 0, 0, 0, 0, 0, NULL}
296 }; 385 };
297 386
298 /***************************************************************************** 387 /*****************************************************************************
339 int d_width; 428 int d_width;
340 int d_height; 429 int d_height;
341 FILE *fvstats; 430 FILE *fvstats;
342 } xvid_mplayer_module_t; 431 } xvid_mplayer_module_t;
343 432
344 static void dispatch_settings(xvid_mplayer_module_t *mod); 433 static int dispatch_settings(xvid_mplayer_module_t *mod);
345 static int set_create_struct(xvid_mplayer_module_t *mod); 434 static int set_create_struct(xvid_mplayer_module_t *mod);
346 static int set_frame_struct(xvid_mplayer_module_t *mod, mp_image_t *mpi); 435 static int set_frame_struct(xvid_mplayer_module_t *mod, mp_image_t *mpi);
347 static void update_stats(xvid_mplayer_module_t *mod, xvid_enc_stats_t *stats); 436 static void update_stats(xvid_mplayer_module_t *mod, xvid_enc_stats_t *stats);
348 static void print_stats(xvid_mplayer_module_t *mod); 437 static void print_stats(xvid_mplayer_module_t *mod);
349 static void flush_internal_buffers(xvid_mplayer_module_t *mod); 438 static void flush_internal_buffers(xvid_mplayer_module_t *mod);
387 *------------------------------------------------------------------*/ 476 *------------------------------------------------------------------*/
388 477
389 mod->d_width = d_width; 478 mod->d_width = d_width;
390 mod->d_height = d_height; 479 mod->d_height = d_height;
391 480
392 dispatch_settings(mod); 481 if(dispatch_settings(mod) == BAD)
482 return(BAD);
393 483
394 /*-------------------------------------------------------------------- 484 /*--------------------------------------------------------------------
395 * Set remaining information in the xvid_enc_create_t structure 485 * Set remaining information in the xvid_enc_create_t structure
396 *------------------------------------------------------------------*/ 486 *------------------------------------------------------------------*/
397 487
628 * Helper functions 718 * Helper functions
629 ****************************************************************************/ 719 ****************************************************************************/
630 720
631 static void *read_matrix(unsigned char *filename); 721 static void *read_matrix(unsigned char *filename);
632 722
633 static void dispatch_settings(xvid_mplayer_module_t *mod) 723 static int dispatch_settings(xvid_mplayer_module_t *mod)
634 { 724 {
635 xvid_enc_create_t *create = &mod->create; 725 xvid_enc_create_t *create = &mod->create;
636 xvid_enc_frame_t *frame = &mod->frame; 726 xvid_enc_frame_t *frame = &mod->frame;
637 xvid_plugin_single_t *onepass = &mod->onepass; 727 xvid_plugin_single_t *onepass = &mod->onepass;
638 xvid_plugin_2pass2_t *pass2 = &mod->pass2; 728 xvid_plugin_2pass2_t *pass2 = &mod->pass2;
639 XVIDRational ar; 729 XVIDRational ar;
730
731 //profile is unrestricted as default
732 profile_t *selected_profile = profileFromName("unrestricted");
733 if(xvidenc_profile)
734 selected_profile = profileFromName(xvidenc_profile);
735 if(!selected_profile)
736 {
737 mp_msg(MSGT_MENCODER,MSGL_ERR,
738 "xvid:[ERROR] \"%s\" is an invalid profile name\n", xvidenc_profile);
739 return(BAD);
740 }
640 741
641 const int motion_presets[7] = 742 const int motion_presets[7] =
642 { 743 {
643 0, 744 0,
644 0, 745 0,
661 * The create structure 762 * The create structure
662 * ---------------------------------------------------------------- */ 763 * ---------------------------------------------------------------- */
663 764
664 create->global = 0; 765 create->global = 0;
665 766
666 if(xvidenc_packed)
667 create->global |= XVID_GLOBAL_PACKED;
668
669 if(xvidenc_closed_gop)
670 create->global |= XVID_GLOBAL_CLOSED_GOP;
671
672 if(xvidenc_psnr) 767 if(xvidenc_psnr)
673 xvidenc_stats = 1; 768 xvidenc_stats = 1;
674 769
675 if(xvidenc_stats) 770 if(xvidenc_stats)
676 create->global |= XVID_GLOBAL_EXTRASTATS_ENABLE; 771 create->global |= XVID_GLOBAL_EXTRASTATS_ENABLE;
678 create->num_zones = 0; 773 create->num_zones = 0;
679 create->zones = NULL; 774 create->zones = NULL;
680 create->num_plugins = 0; 775 create->num_plugins = 0;
681 create->plugins = NULL; 776 create->plugins = NULL;
682 create->num_threads = 0; 777 create->num_threads = 0;
778
779 if( (selected_profile->flags & PROFILE_BVOP) &&
780 /* dxn: prevent bframes usage if interlacing is selected */
781 !((selected_profile->flags & PROFILE_DXN) && xvidenc_interlaced) )
782 {
683 create->max_bframes = xvidenc_max_bframes; 783 create->max_bframes = xvidenc_max_bframes;
684 create->bquant_ratio = xvidenc_bquant_ratio; 784 create->bquant_ratio = xvidenc_bquant_ratio;
685 create->bquant_offset = xvidenc_bquant_offset; 785 create->bquant_offset = xvidenc_bquant_offset;
786 if(xvidenc_packed)
787 create->global |= XVID_GLOBAL_PACKED;
788 if(xvidenc_closed_gop)
789 create->global |= XVID_GLOBAL_CLOSED_GOP;
790
791 /* dxn: restrict max bframes, require closed gop
792 and require packed b-frames */
793 if(selected_profile->flags & PROFILE_DXN)
794 {
795 if(create->max_bframes > selected_profile->dxn_max_bframes)
796 create->max_bframes = selected_profile->dxn_max_bframes;
797 create->global |= XVID_GLOBAL_CLOSED_GOP;
798 create->global |= XVID_GLOBAL_PACKED;
799 }
800 }
801 else
802 create->max_bframes = 0;
803
804 /* dxn: always write divx5 userdata */
805 if(selected_profile->flags & PROFILE_DXN)
806 create->global |= XVID_GLOBAL_DIVX5_USERDATA;
807
686 create->max_key_interval = xvidenc_max_key_interval; 808 create->max_key_interval = xvidenc_max_key_interval;
687 create->frame_drop_ratio = xvidenc_frame_drop_ratio; 809 create->frame_drop_ratio = xvidenc_frame_drop_ratio;
688 create->min_quant[0] = xvidenc_min_quant[0]; 810 create->min_quant[0] = xvidenc_min_quant[0];
689 create->min_quant[1] = xvidenc_min_quant[1]; 811 create->min_quant[1] = xvidenc_min_quant[1];
690 create->min_quant[2] = xvidenc_min_quant[2]; 812 create->min_quant[2] = xvidenc_min_quant[2];
715 pass2->max_overflow_degradation = xvidenc_vbr_max_overflow_degradation; 837 pass2->max_overflow_degradation = xvidenc_vbr_max_overflow_degradation;
716 pass2->kfreduction = xvidenc_vbr_kfreduction; 838 pass2->kfreduction = xvidenc_vbr_kfreduction;
717 pass2->kfthreshold = xvidenc_vbr_kfthreshold; 839 pass2->kfthreshold = xvidenc_vbr_kfthreshold;
718 pass2->container_frame_overhead = xvidenc_vbr_container_frame_overhead; 840 pass2->container_frame_overhead = xvidenc_vbr_container_frame_overhead;
719 841
842 /* VBV */
843
844 pass2->vbv_size = selected_profile->max_vbv_size;
845 pass2->vbv_initial = (selected_profile->max_vbv_size*3)>>2; /* 75% */
846 pass2->vbv_maxrate = selected_profile->max_bitrate;
847 pass2->vbv_peakrate = selected_profile->vbv_peakrate*3;
848 // XXX: xvidcore currently provides a "peak bits over 3 seconds" constraint.
849 // according to the latest dxn literature, a 1 second constraint is now used
850
851 create->profile = selected_profile->id;
852
720 /* ------------------------------------------------------------------- 853 /* -------------------------------------------------------------------
721 * The frame structure 854 * The frame structure
722 * ---------------------------------------------------------------- */ 855 * ---------------------------------------------------------------- */
723 frame->vol_flags = 0; 856 frame->vol_flags = 0;
724 frame->vop_flags = 0; 857 frame->vop_flags = 0;
736 if(xvidenc_cartoon) { 869 if(xvidenc_cartoon) {
737 frame->vop_flags |= XVID_VOP_CARTOON; 870 frame->vop_flags |= XVID_VOP_CARTOON;
738 frame->motion |= XVID_ME_DETECT_STATIC_MOTION; 871 frame->motion |= XVID_ME_DETECT_STATIC_MOTION;
739 } 872 }
740 873
874 // MPEG quantisation is only supported in ASP and unrestricted profiles
875 if((selected_profile->flags & PROFILE_MPEGQUANT) &&
876 (xvidenc_quant_method != NULL) &&
877 !strcasecmp(xvidenc_quant_method, "mpeg"))
878 {
879 frame->vol_flags |= XVID_VOL_MPEGQUANT;
741 if(xvidenc_intra_matrix_file != NULL) { 880 if(xvidenc_intra_matrix_file != NULL) {
742 frame->quant_intra_matrix = (unsigned char*)read_matrix(xvidenc_intra_matrix_file); 881 frame->quant_intra_matrix = (unsigned char*)read_matrix(xvidenc_intra_matrix_file);
743 if(frame->quant_intra_matrix != NULL) { 882 if(frame->quant_intra_matrix != NULL) {
744 mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: Loaded Intra matrix (switching to mpeg quantization type)\n"); 883 mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: Loaded Intra matrix (switching to mpeg quantization type)\n");
745 if(xvidenc_quant_method) free(xvidenc_quant_method); 884 if(xvidenc_quant_method) free(xvidenc_quant_method);
752 mp_msg(MSGT_MENCODER, MSGL_INFO, "\nxvid: Loaded Inter matrix (switching to mpeg quantization type)\n"); 891 mp_msg(MSGT_MENCODER, MSGL_INFO, "\nxvid: Loaded Inter matrix (switching to mpeg quantization type)\n");
753 if(xvidenc_quant_method) free(xvidenc_quant_method); 892 if(xvidenc_quant_method) free(xvidenc_quant_method);
754 xvidenc_quant_method = strdup("mpeg"); 893 xvidenc_quant_method = strdup("mpeg");
755 } 894 }
756 } 895 }
757 if(xvidenc_quant_method != NULL && !strcasecmp(xvidenc_quant_method, "mpeg")) { 896 }
758 frame->vol_flags |= XVID_VOL_MPEGQUANT; 897 if(xvidenc_quarterpel && (selected_profile->flags & PROFILE_QPEL)) {
759 }
760 if(xvidenc_quarterpel) {
761 frame->vol_flags |= XVID_VOL_QUARTERPEL; 898 frame->vol_flags |= XVID_VOL_QUARTERPEL;
762 frame->motion |= XVID_ME_QUARTERPELREFINE16; 899 frame->motion |= XVID_ME_QUARTERPELREFINE16;
763 frame->motion |= XVID_ME_QUARTERPELREFINE8; 900 frame->motion |= XVID_ME_QUARTERPELREFINE8;
764 } 901 }
765 if(xvidenc_gmc) { 902 if(xvidenc_gmc && (selected_profile->flags & PROFILE_GMC)) {
766 frame->vol_flags |= XVID_VOL_GMC; 903 frame->vol_flags |= XVID_VOL_GMC;
767 frame->motion |= XVID_ME_GME_REFINE; 904 frame->motion |= XVID_ME_GME_REFINE;
768 } 905 }
769 if(xvidenc_interlaced) { 906 if(xvidenc_interlaced && (selected_profile->flags & PROFILE_INTERLACE)) {
770 frame->vol_flags |= XVID_VOL_INTERLACING; 907 frame->vol_flags |= XVID_VOL_INTERLACING;
771 } 908 }
772 if(xvidenc_trellis) { 909 if(xvidenc_trellis) {
773 frame->vop_flags |= XVID_VOP_TRELLISQUANT; 910 frame->vop_flags |= XVID_VOP_TRELLISQUANT;
774 } 911 }
776 frame->vop_flags |= XVID_VOP_HQACPRED; 913 frame->vop_flags |= XVID_VOP_HQACPRED;
777 } 914 }
778 if(xvidenc_chroma_opt) { 915 if(xvidenc_chroma_opt) {
779 frame->vop_flags |= XVID_VOP_CHROMAOPT; 916 frame->vop_flags |= XVID_VOP_CHROMAOPT;
780 } 917 }
781 if(xvidenc_motion > 4) { 918 if((xvidenc_motion > 4) && (selected_profile->flags & PROFILE_4MV)) {
782 frame->vop_flags |= XVID_VOP_INTER4V; 919 frame->vop_flags |= XVID_VOP_INTER4V;
783 } 920 }
784 if(xvidenc_chromame) { 921 if(xvidenc_chromame) {
785 frame->motion |= XVID_ME_CHROMA_PVOP; 922 frame->motion |= XVID_ME_CHROMA_PVOP;
786 frame->motion |= XVID_ME_CHROMA_BVOP; 923 frame->motion |= XVID_ME_CHROMA_BVOP;
824 frame->bframe_threshold = xvidenc_bframe_threshold; 961 frame->bframe_threshold = xvidenc_bframe_threshold;
825 962
826 /* PAR related initialization */ 963 /* PAR related initialization */
827 frame->par = XVID_PAR_11_VGA; /* Default */ 964 frame->par = XVID_PAR_11_VGA; /* Default */
828 965
966 if( !(selected_profile->flags & PROFILE_DXN) )
967 {
829 if(xvidenc_dar_aspect > 0) 968 if(xvidenc_dar_aspect > 0)
830 ar = xvid_d2q(xvidenc_dar_aspect * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255); 969 ar = xvid_d2q(xvidenc_dar_aspect * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255);
831 else if(xvidenc_autoaspect) 970 else if(xvidenc_autoaspect)
832 ar = xvid_d2q((float)mod->d_width / mod->d_height * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255); 971 ar = xvid_d2q((float)mod->d_width / mod->d_height * mod->mux->bih->biHeight / mod->mux->bih->biWidth, 255);
833 else ar.num = ar.den = 0; 972 else ar.num = ar.den = 0;
875 1014
876 /* Display par information */ 1015 /* Display par information */
877 mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: par=%d/%d (%s), displayed=%dx%d, sampled=%dx%d\n", 1016 mp_msg(MSGT_MENCODER, MSGL_INFO, "xvid: par=%d/%d (%s), displayed=%dx%d, sampled=%dx%d\n",
878 ar.num, ar.den, par_string(frame->par), 1017 ar.num, ar.den, par_string(frame->par),
879 mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight); 1018 mod->d_width, mod->d_height, mod->mux->bih->biWidth, mod->mux->bih->biHeight);
880 return; 1019 }
1020 else
1021 mp_msg(MSGT_MENCODER, MSGL_INFO,
1022 "xvid: par=0/0 (vga11) forced by choosing a DXN profile\n");
1023 return(FINE);
881 } 1024 }
882 1025
883 static int set_create_struct(xvid_mplayer_module_t *mod) 1026 static int set_create_struct(xvid_mplayer_module_t *mod)
884 { 1027 {
885 int pass; 1028 int pass;
886 int doZones = 0; 1029 int doZones = 0;
887 xvid_enc_create_t *create = &mod->create; 1030 xvid_enc_create_t *create = &mod->create;
888 1031
1032 // profile is unrestricted as default
1033 profile_t *selected_profile = profileFromName("unrestricted");
1034 if(xvidenc_profile)
1035 selected_profile = profileFromName(xvidenc_profile);
1036 if(!selected_profile)
1037 return(BAD);
1038
889 /* Most of the structure is initialized by dispatch settings, only a 1039 /* Most of the structure is initialized by dispatch settings, only a
890 * few things are missing */ 1040 * few things are missing */
891 create->version = XVID_VERSION; 1041 create->version = XVID_VERSION;
892 1042
893 /* Width and Height */ 1043 /* Width and Height */
894 create->width = mod->mux->bih->biWidth; 1044 create->width = mod->mux->bih->biWidth;
895 create->height = mod->mux->bih->biHeight; 1045 create->height = mod->mux->bih->biHeight;
896 1046
1047 /* Check resolution of video to be coded is within profile width/height
1048 restrictions */
1049 if( ((selected_profile->width != 0) &&
1050 (mod->mux->bih->biWidth > selected_profile->width)) ||
1051 ((selected_profile->height != 0) &&
1052 (mod->mux->bih->biHeight > selected_profile->height)) )
1053 {
1054 mp_msg(MSGT_MENCODER,MSGL_ERR,
1055 "xvid:[ERROR] resolution must be <= %dx%d for the chosen profile\n",
1056 selected_profile->width, selected_profile->height);
1057 return(BAD);
1058 }
1059
897 /* FPS */ 1060 /* FPS */
898 create->fincr = mod->mux->h.dwScale; 1061 create->fincr = mod->mux->h.dwScale;
899 create->fbase = mod->mux->h.dwRate; 1062 create->fbase = mod->mux->h.dwRate;
1063
1064 // Check frame rate is within profile restrictions
1065 if( ((float)mod->mux->h.dwRate/(float)mod->mux->h.dwScale > (float)selected_profile->fps) &&
1066 (selected_profile->fps != 0))
1067 {
1068 mp_msg(MSGT_MENCODER,MSGL_ERR,
1069 "xvid:[ERROR] frame rate must be <= %d for the chosen profile\n",
1070 selected_profile->fps);
1071 return(BAD);
1072 }
900 1073
901 /* Encodings zones */ 1074 /* Encodings zones */
902 memset(mod->zones, 0, sizeof(mod->zones)); 1075 memset(mod->zones, 0, sizeof(mod->zones));
903 create->zones = mod->zones; 1076 create->zones = mod->zones;
904 create->num_zones = 0; 1077 create->num_zones = 0;
1051 create->plugins[create->num_plugins].param = pass2; 1224 create->plugins[create->num_plugins].param = pass2;
1052 create->num_plugins++; 1225 create->num_plugins++;
1053 doZones = 1; 1226 doZones = 1;
1054 } 1227 }
1055 1228
1056 if (xvidenc_luminance_masking) { 1229 if(xvidenc_luminance_masking && (selected_profile->flags & PROFILE_ADAPTQUANT)) {
1057 create->plugins[create->num_plugins].func = xvid_plugin_lumimasking; 1230 create->plugins[create->num_plugins].func = xvid_plugin_lumimasking;
1058 create->plugins[create->num_plugins].param = NULL; 1231 create->plugins[create->num_plugins].param = NULL;
1059 create->num_plugins++; 1232 create->num_plugins++;
1060 } 1233 }
1061 1234