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 // 16 is probably overkill but it's also the maximum for h.264 reference frames
27 #define MAX_INFLIGHT_FRAMES 16
29 struct hb_work_private_s
33 x264_picture_t pic_in;
35 // Internal queue of DTS start/stop values.
36 int64_t dts_start[MAX_INFLIGHT_FRAMES];
37 int64_t dts_stop[MAX_INFLIGHT_FRAMES];
39 int64_t dts_write_index;
40 int64_t dts_read_index;
45 /***********************************************************************
46 * hb_work_encx264_init
47 ***********************************************************************
49 **********************************************************************/
50 int encx264Init( hb_work_object_t * w, hb_job_t * job )
56 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
61 memset( pv->filename, 0, 1024 );
62 hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
64 x264_param_default( ¶m );
66 param.i_threads = ( hb_get_cpu_count() * 3 / 2 );
67 param.i_width = job->width;
68 param.i_height = job->height;
69 param.i_fps_num = job->vrate;
70 param.i_fps_den = job->vrate_base;
71 param.i_keyint_max = 20 * job->vrate / job->vrate_base;
72 param.i_log_level = X264_LOG_INFO;
77 param.i_level_idc = job->h264_level;
78 hb_log( "encx264: encoding at level %i",
82 /* Slightly faster with minimal quality lost */
83 param.analyse.i_subpel_refine = 4;
86 This section passes the string x264opts to libx264 for parsing into
87 parameter names and values.
89 The string is set up like this:
90 option1=value1:option2=value 2
92 So, you have to iterate through based on the colons, and then put
93 the left side of the equals sign in "name" and the right side into
94 "value." Then you hand those strings off to x264 for interpretation.
96 This is all based on the universal x264 option handling Loren
97 Merritt implemented in the Mplayer/Mencoder project.
100 char *x264opts = job->x264opts;
101 if( x264opts != NULL && *x264opts != '\0' )
105 char *name = x264opts;
109 x264opts += strcspn( x264opts, ":" );
116 value = strchr( name, '=' );
124 When B-frames are enabled, the max frame count increments
125 by 1 (regardless of the number of B-frames). If you don't
126 change the duration of the video track when you mux, libmp4
127 barfs. So, check if the x264opts are using B-frames, and
128 when they are, set the boolean job->areBframes as true.
131 if( !( strcmp( name, "bframes" ) ) )
133 if( atoi( value ) > 0 )
139 /* Note b-pyramid here, so the initial delay can be doubled */
140 if( !( strcmp( name, "b-pyramid" ) ) )
144 if( atoi( value ) > 0 )
155 /* Here's where the strings are passed to libx264 for parsing. */
156 ret = x264_param_parse( ¶m, name, value );
158 /* Let x264 sanity check the options for us*/
159 if( ret == X264_PARAM_BAD_NAME )
160 hb_log( "x264 options: Unknown suboption %s", name );
161 if( ret == X264_PARAM_BAD_VALUE )
162 hb_log( "x264 options: Bad argument %s=%s", name, value ? value : "(null)" );
167 if( job->pixel_ratio )
169 param.vui.i_sar_width = job->pixel_aspect_width;
170 param.vui.i_sar_height = job->pixel_aspect_height;
172 hb_log( "encx264: encoding with stored aspect %d/%d",
173 param.vui.i_sar_width, param.vui.i_sar_height );
177 if( job->vquality >= 0.0 && job->vquality <= 1.0 )
183 param.rc.i_rc_method = X264_RC_CRF;
184 param.rc.f_rf_constant = 51 - job->vquality * 51;
185 hb_log( "encx264: Encoding at constant RF %f",
186 param.rc.f_rf_constant );
191 param.rc.i_rc_method = X264_RC_CQP;
192 param.rc.i_qp_constant = 51 - job->vquality * 51;
193 hb_log( "encx264: encoding at constant QP %d",
194 param.rc.i_qp_constant );
201 param.rc.i_rc_method = X264_RC_ABR;
202 param.rc.i_bitrate = job->vbitrate;
206 param.rc.b_stat_write = 1;
207 param.rc.psz_stat_out = pv->filename;
210 param.rc.b_stat_read = 1;
211 param.rc.psz_stat_in = pv->filename;
216 hb_log( "encx264: opening libx264 (pass %d)", job->pass );
217 pv->x264 = x264_encoder_open( ¶m );
219 x264_encoder_headers( pv->x264, &nal, &nal_count );
221 /* Sequence Parameter Set */
222 w->config->h264.sps_length = 1 + nal[1].i_payload;
223 w->config->h264.sps[0] = 0x67;
224 memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
226 /* Picture Parameter Set */
227 w->config->h264.pps_length = 1 + nal[2].i_payload;
228 w->config->h264.pps[0] = 0x68;
229 memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
231 x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
232 job->width, job->height );
234 pv->dts_write_index = 0;
235 pv->dts_read_index = 0;
240 void encx264Close( hb_work_object_t * w )
242 hb_work_private_t * pv = w->private_data;
243 x264_picture_clean( &pv->pic_in );
244 x264_encoder_close( pv->x264 );
246 w->private_data = NULL;
251 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
252 hb_buffer_t ** buf_out )
254 hb_work_private_t * pv = w->private_data;
255 hb_job_t * job = pv->job;
256 hb_buffer_t * in = *buf_in, * buf;
257 x264_picture_t pic_out;
264 /* XXX avoid this memcpy ? */
265 memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
268 /* XXX x264 has currently no option for grayscale encoding */
269 memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
270 memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
274 memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
275 job->width * job->height / 4 );
276 memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
277 job->height / 4, job->width * job->height / 4 );
280 pv->pic_in.i_type = X264_TYPE_AUTO;
281 pv->pic_in.i_qpplus1 = 0;
283 // Remember current PTS value, use as DTS later
284 pv->dts_start[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->start;
285 pv->dts_stop[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->stop;
286 pv->dts_write_index++;
288 /* Feed the input DTS to x264 so it can figure out proper output PTS */
289 pv->pic_in.i_pts = in->start;
291 x264_encoder_encode( pv->x264, &nal, &i_nal,
292 &pv->pic_in, &pic_out );
296 x264_encoder_encode( pv->x264, &nal, &i_nal,
298 /* No more delayed B frames */
306 /* Since we output at least one more frame, drop another empty
307 one onto our input fifo. We'll keep doing this automatically
308 until we stop getting frames out of the encoder. */
309 hb_fifo_push(w->fifo_in, hb_buffer_init(0));
315 /* Should be way too large */
316 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
318 buf->start = in->start;
319 buf->stop = in->stop;
322 int64_t dts_start, dts_stop;
324 /* Get next DTS value to use */
325 dts_start = pv->dts_start[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
326 dts_stop = pv->dts_stop[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
327 pv->dts_read_index++;
329 for( i = 0; i < i_nal; i++ )
333 data = buf->alloc - buf->size;
334 if( ( size = x264_nal_encode( buf->data + buf->size, &data,
340 if( job->mux & HB_MUX_AVI )
342 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
351 switch( buf->data[buf->size+4] & 0x1f )
359 /* H.264 in mp4 (stolen from mp4creator) */
360 buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
361 buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
362 buf->data[buf->size+2] = ( ( size - 4 ) >> 8 ) & 0xFF;
363 buf->data[buf->size+3] = ( ( size - 4 ) >> 0 ) & 0xFF;
364 switch( pic_out.i_type )
366 /* For IDR (key frames), buf->key = 1,
367 and the same for regular I-frames. */
372 /* For B-frames, buf->key = 2 */
376 /* This is for b-pyramid, which has reference b-frames
377 However, it doesn't seem to ever be used...
378 They just show up as buf->key == 2 like
383 /* For P-frames, buf->key = 0 */
389 /* Store the output presentation time stamp
390 from x264 for use by muxmp4 in off-setting
391 b-frames with the CTTS atom.
392 For now, just add 1000000 to the offset so that the
393 value is pretty much guaranteed to be positive. The
394 muxing code will minimize the renderOffset at the end. */
396 buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
398 /* Send out the next dts values */
399 buf->start = dts_start;
400 buf->stop = dts_stop;