Mercurial > mplayer.hg
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 |