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 w
->private_data
= NULL
;
139 /***********************************************************************
141 ***********************************************************************
143 **********************************************************************/
144 int encxvidWork( hb_work_object_t
* w
, hb_buffer_t
** buf_in
,
145 hb_buffer_t
** buf_out
)
147 hb_work_private_t
* pv
= w
->private_data
;
148 hb_job_t
* job
= pv
->job
;
149 xvid_enc_frame_t frame
;
150 hb_buffer_t
* in
= *buf_in
, * buf
;
152 /* If this is the last empty frame, we're done */
159 /* Should be way too large */
160 buf
= hb_buffer_init( 3 * job
->width
* job
->height
/ 2 );
161 buf
->start
= in
->start
;
162 buf
->stop
= in
->stop
;
163 //buf->chap = in->chap;
165 memset( &frame
, 0, sizeof( frame
) );
167 frame
.version
= XVID_VERSION
;
168 frame
.bitstream
= buf
->data
;
170 frame
.input
.plane
[0] = in
->data
;
171 frame
.input
.csp
= XVID_CSP_I420
;
172 frame
.input
.stride
[0] = job
->width
;
174 frame
.vop_flags
= XVID_VOP_HALFPEL
| XVID_VOP_INTER4V
|
175 XVID_VOP_TRELLISQUANT
| XVID_VOP_HQACPRED
;
176 if( job
->pixel_ratio
)
178 frame
.par
= XVID_PAR_EXT
;
179 frame
.par_width
= job
->pixel_aspect_width
;
180 frame
.par_height
= job
->pixel_aspect_height
;
185 frame
.vop_flags
|= XVID_VOP_GREYSCALE
;
187 frame
.type
= XVID_TYPE_AUTO
;
188 frame
.quant
= pv
->quant
;
189 frame
.motion
= XVID_ME_ADVANCEDDIAMOND16
| XVID_ME_HALFPELREFINE16
|
190 XVID_ME_EXTSEARCH16
| XVID_ME_ADVANCEDDIAMOND8
|
191 XVID_ME_HALFPELREFINE8
| XVID_ME_EXTSEARCH8
|
192 XVID_ME_CHROMA_PVOP
| XVID_ME_CHROMA_BVOP
;
193 frame
.quant_intra_matrix
= NULL
;
194 frame
.quant_inter_matrix
= NULL
;
196 buf
->size
= xvid_encore( pv
->xvid
, XVID_ENC_ENCODE
, &frame
, NULL
);
197 buf
->frametype
= ( frame
.out_flags
& XVID_KEYFRAME
) ? HB_FRAME_KEY
: HB_FRAME_REF
;
199 if( !pv
->configDone
)
201 int vol_start
, vop_start
;
202 for( vol_start
= 0; ; vol_start
++ )
204 if( buf
->data
[vol_start
] == 0x0 &&
205 buf
->data
[vol_start
+1] == 0x0 &&
206 buf
->data
[vol_start
+2] == 0x1 &&
207 buf
->data
[vol_start
+3] == 0x20 )
212 for( vop_start
= vol_start
+ 4; ; vop_start
++ )
214 if( buf
->data
[vop_start
] == 0x0 &&
215 buf
->data
[vop_start
+1] == 0x0 &&
216 buf
->data
[vop_start
+2] == 0x1 &&
217 buf
->data
[vop_start
+3] == 0xB6 )
223 hb_log( "encxvid: VOL size is %d bytes", vop_start
- vol_start
);
224 job
->config
.mpeg4
.length
= vop_start
- vol_start
;
225 memcpy( job
->config
.mpeg4
.bytes
, &buf
->data
[vol_start
],
226 job
->config
.mpeg4
.length
);