1 /* $Id: encx264.c,v 1.21 2005/11/04 13:09:41 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. */
13 int encx264Init( hb_work_object_t *, hb_job_t * );
14 int encx264Work( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
15 void encx264Close( hb_work_object_t * );
17 hb_work_object_t hb_encx264 =
20 "H.264/AVC encoder (libx264)",
26 struct hb_work_private_s
30 x264_picture_t pic_in;
31 x264_picture_t pic_out;
36 /***********************************************************************
37 * hb_work_encx264_init
38 ***********************************************************************
40 **********************************************************************/
41 int encx264Init( hb_work_object_t * w, hb_job_t * job )
47 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
52 memset( pv->filename, 0, 1024 );
53 hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
55 x264_param_default( ¶m );
57 param.i_threads = hb_get_cpu_count();
58 param.i_width = job->width;
59 param.i_height = job->height;
60 param.i_fps_num = job->vrate;
61 param.i_fps_den = job->vrate_base;
62 param.i_keyint_max = 20 * job->vrate / job->vrate_base;
63 param.i_log_level = X264_LOG_NONE;
68 param.i_level_idc = job->h264_level;
69 hb_log( "encx264: encoding at level %i",
73 /* Slightly faster with minimal quality lost */
74 param.analyse.i_subpel_refine = 4;
76 if( job->pixel_ratio )
78 param.vui.i_sar_width = job->pixel_aspect_width;
79 param.vui.i_sar_height = job->pixel_aspect_height;
81 hb_log( "encx264: encoding with stored aspect %d/%d",
82 param.vui.i_sar_width, param.vui.i_sar_height );
86 if( job->vquality >= 0.0 && job->vquality <= 1.0 )
92 param.rc.i_rc_method = X264_RC_CRF;
93 param.rc.f_rf_constant = 51 - job->vquality * 51;
94 hb_log( "encx264: Encoding at constant RF %f",
95 param.rc.f_rf_constant );
100 param.rc.i_rc_method = X264_RC_CQP;
101 param.rc.i_qp_constant = 51 - job->vquality * 51;
102 hb_log( "encx264: encoding at constant QP %d",
103 param.rc.i_qp_constant );
110 param.rc.i_rc_method = X264_RC_ABR;
111 param.rc.i_bitrate = job->vbitrate;
115 param.rc.b_stat_write = 1;
116 param.rc.psz_stat_out = pv->filename;
119 param.rc.b_stat_read = 1;
120 param.rc.psz_stat_in = pv->filename;
125 hb_log( "encx264: opening libx264 (pass %d)", job->pass );
126 pv->x264 = x264_encoder_open( ¶m );
128 x264_encoder_headers( pv->x264, &nal, &nal_count );
130 /* Sequence Parameter Set */
131 w->config->h264.sps_length = 1 + nal[1].i_payload;
132 w->config->h264.sps[0] = 0x67;
133 memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
135 /* Picture Parameter Set */
136 w->config->h264.pps_length = 1 + nal[2].i_payload;
137 w->config->h264.pps[0] = 0x68;
138 memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
140 x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
141 job->width, job->height );
146 void encx264Close( hb_work_object_t * w )
148 hb_work_private_t * pv = w->private_data;
149 x264_encoder_close( pv->x264 );
154 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
155 hb_buffer_t ** buf_out )
157 hb_work_private_t * pv = w->private_data;
158 hb_job_t * job = pv->job;
159 hb_buffer_t * in = *buf_in, * buf;
164 /* XXX avoid this memcpy ? */
165 memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
168 /* XXX x264 has currently no option for grayscale encoding */
169 memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
170 memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
174 memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
175 job->width * job->height / 4 );
176 memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
177 job->height / 4, job->width * job->height / 4 );
180 pv->pic_in.i_type = X264_TYPE_AUTO;
181 pv->pic_in.i_qpplus1 = 0;
183 x264_encoder_encode( pv->x264, &nal, &i_nal,
184 &pv->pic_in, &pv->pic_out );
186 /* Should be way too large */
187 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
189 buf->start = in->start;
190 buf->stop = in->stop;
193 for( i = 0; i < i_nal; i++ )
197 data = buf->alloc - buf->size;
198 if( ( size = x264_nal_encode( buf->data + buf->size, &data,
204 if( job->mux & HB_MUX_AVI )
206 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
215 switch( buf->data[buf->size+4] & 0x1f )
223 /* H.264 in mp4 (stolen from mp4creator) */
224 buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
225 buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
226 buf->data[buf->size+2] = ( ( size - 4 ) >> 8 ) & 0xFF;
227 buf->data[buf->size+3] = ( ( size - 4 ) >> 0 ) & 0xFF;
228 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )