1 /* $Id: encxvid.c,v 1.10 2005/03/09 23:28:39 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
11 int encxvidInit( hb_work_object_t *, hb_job_t * );
12 int encxvidWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
13 void encxvidClose( hb_work_object_t * );
15 hb_work_object_t hb_encxvid =
18 "MPEG-4 encoder (libxvidcore)",
24 struct hb_work_private_s
33 int encxvidInit( hb_work_object_t * w, hb_job_t * job )
35 xvid_gbl_init_t xvid_gbl_init;
36 xvid_enc_create_t create;
37 xvid_plugin_single_t single;
38 xvid_plugin_2pass1_t rc2pass1;
39 xvid_plugin_2pass2_t rc2pass2;
40 xvid_enc_plugin_t plugins[1];
42 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
47 memset( pv->filename, 0, 1024 );
48 hb_get_tempory_filename( job->h, pv->filename, "xvid.log" );
50 memset( &xvid_gbl_init, 0, sizeof( xvid_gbl_init ) );
51 xvid_gbl_init.version = XVID_VERSION;
52 xvid_global( NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL );
54 memset( &create, 0, sizeof( create ) );
55 create.version = XVID_VERSION;
56 create.width = job->width;
57 create.height = job->height;
64 memset( &single, 0, sizeof( single ) );
65 single.version = XVID_VERSION;
66 if( job->vquality < 0.0 || job->vquality > 1.0 )
69 single.bitrate = 1000 * job->vbitrate;
74 /* Constant quantizer */
75 pv->quant = 31 - job->vquality * 30;
76 hb_log( "encxvid: encoding at constant quantizer %d",
79 plugins[0].func = xvid_plugin_single;
80 plugins[0].param = &single;
84 memset( &rc2pass1, 0, sizeof( rc2pass1 ) );
85 rc2pass1.version = XVID_VERSION;
86 rc2pass1.filename = pv->filename;
87 plugins[0].func = xvid_plugin_2pass1;
88 plugins[0].param = &rc2pass1;
92 memset( &rc2pass2, 0, sizeof( rc2pass2 ) );
93 rc2pass2.version = XVID_VERSION;
94 rc2pass2.filename = pv->filename;
95 rc2pass2.bitrate = 1000 * job->vbitrate;
96 plugins[0].func = xvid_plugin_2pass2;
97 plugins[0].param = &rc2pass2;
101 create.plugins = plugins;
102 create.num_plugins = 1;
104 create.num_threads = 0;
105 create.fincr = job->vrate_base;
106 create.fbase = job->vrate;
107 create.max_key_interval = 10 * job->vrate / job->vrate_base;
108 create.max_bframes = 0;
109 create.bquant_ratio = 150;
110 create.bquant_offset = 100;
111 create.frame_drop_ratio = 0;
114 xvid_encore( NULL, XVID_ENC_CREATE, &create, NULL );
115 pv->xvid = create.handle;
120 /***********************************************************************
122 ***********************************************************************
124 **********************************************************************/
125 void encxvidClose( hb_work_object_t * w )
127 hb_work_private_t * pv = w->private_data;
131 hb_log( "encxvid: closing libxvidcore" );
132 xvid_encore( pv->xvid, XVID_ENC_DESTROY, NULL, NULL);
136 /***********************************************************************
138 ***********************************************************************
140 **********************************************************************/
141 int encxvidWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
142 hb_buffer_t ** buf_out )
144 hb_work_private_t * pv = w->private_data;
145 hb_job_t * job = pv->job;
146 xvid_enc_frame_t frame;
147 hb_buffer_t * in = *buf_in, * buf;
149 /* Should be way too large */
150 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
151 buf->start = in->start;
152 buf->stop = in->stop;
154 memset( &frame, 0, sizeof( frame ) );
156 frame.version = XVID_VERSION;
157 frame.bitstream = buf->data;
159 frame.input.plane[0] = in->data;
160 frame.input.csp = XVID_CSP_I420;
161 frame.input.stride[0] = job->width;
163 frame.vop_flags = XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
164 XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED;
165 if( job->pixel_ratio )
167 frame.par = XVID_PAR_EXT;
168 frame.par_width = job->pixel_aspect_width;
169 frame.par_height = job->pixel_aspect_height;
174 frame.vop_flags |= XVID_VOP_GREYSCALE;
176 frame.type = XVID_TYPE_AUTO;
177 frame.quant = pv->quant;
178 frame.motion = XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
179 XVID_ME_EXTSEARCH16 | XVID_ME_ADVANCEDDIAMOND8 |
180 XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |
181 XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP;
182 frame.quant_intra_matrix = NULL;
183 frame.quant_inter_matrix = NULL;
185 buf->size = xvid_encore( pv->xvid, XVID_ENC_ENCODE, &frame, NULL );
186 buf->key = ( frame.out_flags & XVID_KEYFRAME );
188 if( !pv->configDone )
190 int vol_start, vop_start;
191 for( vol_start = 0; ; vol_start++ )
193 if( buf->data[vol_start] == 0x0 &&
194 buf->data[vol_start+1] == 0x0 &&
195 buf->data[vol_start+2] == 0x1 &&
196 buf->data[vol_start+3] == 0x20 )
201 for( vop_start = vol_start + 4; ; vop_start++ )
203 if( buf->data[vop_start] == 0x0 &&
204 buf->data[vop_start+1] == 0x0 &&
205 buf->data[vop_start+2] == 0x1 &&
206 buf->data[vop_start+3] == 0xB6 )
212 hb_log( "encxvid: VOL size is %d bytes", vop_start - vol_start );
213 job->config.mpeg4.length = vop_start - vol_start;
214 memcpy( job->config.mpeg4.bytes, &buf->data[vol_start],
215 job->config.mpeg4.length );