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;
46 /***********************************************************************
47 * hb_work_encx264_init
48 ***********************************************************************
50 **********************************************************************/
51 int encx264Init( hb_work_object_t * w, hb_job_t * job )
57 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
62 memset( pv->filename, 0, 1024 );
63 hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
65 x264_param_default( ¶m );
67 param.i_threads = ( hb_get_cpu_count() * 3 / 2 );
68 param.i_width = job->width;
69 param.i_height = job->height;
70 param.i_fps_num = job->vrate;
71 param.i_fps_den = job->vrate_base;
72 param.i_keyint_max = 20 * job->vrate / job->vrate_base;
73 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 if( job->x264opts != NULL && *job->x264opts != '\0' )
102 char *x264opts = strdup(job->x264opts);
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)" );
168 if( job->pixel_ratio )
170 param.vui.i_sar_width = job->pixel_aspect_width;
171 param.vui.i_sar_height = job->pixel_aspect_height;
173 hb_log( "encx264: encoding with stored aspect %d/%d",
174 param.vui.i_sar_width, param.vui.i_sar_height );
178 if( job->vquality >= 0.0 && job->vquality <= 1.0 )
184 param.rc.i_rc_method = X264_RC_CRF;
185 param.rc.f_rf_constant = 51 - job->vquality * 51;
186 hb_log( "encx264: Encoding at constant RF %f",
187 param.rc.f_rf_constant );
192 param.rc.i_rc_method = X264_RC_CQP;
193 param.rc.i_qp_constant = 51 - job->vquality * 51;
194 hb_log( "encx264: encoding at constant QP %d",
195 param.rc.i_qp_constant );
202 param.rc.i_rc_method = X264_RC_ABR;
203 param.rc.i_bitrate = job->vbitrate;
207 param.rc.b_stat_write = 1;
208 param.rc.psz_stat_out = pv->filename;
211 param.rc.b_stat_read = 1;
212 param.rc.psz_stat_in = pv->filename;
217 hb_log( "encx264: opening libx264 (pass %d)", job->pass );
218 pv->x264 = x264_encoder_open( ¶m );
220 x264_encoder_headers( pv->x264, &nal, &nal_count );
222 /* Sequence Parameter Set */
223 w->config->h264.sps_length = 1 + nal[1].i_payload;
224 w->config->h264.sps[0] = 0x67;
225 memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
227 /* Picture Parameter Set */
228 w->config->h264.pps_length = 1 + nal[2].i_payload;
229 w->config->h264.pps[0] = 0x68;
230 memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
232 x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
233 job->width, job->height );
235 pv->dts_write_index = 0;
236 pv->dts_read_index = 0;
242 void encx264Close( hb_work_object_t * w )
244 hb_work_private_t * pv = w->private_data;
245 x264_picture_clean( &pv->pic_in );
246 x264_encoder_close( pv->x264 );
248 w->private_data = NULL;
253 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
254 hb_buffer_t ** buf_out )
256 hb_work_private_t * pv = w->private_data;
257 hb_job_t * job = pv->job;
258 hb_buffer_t * in = *buf_in, * buf;
259 x264_picture_t pic_out;
266 /* XXX avoid this memcpy ? */
267 memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
270 /* XXX x264 has currently no option for grayscale encoding */
271 memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
272 memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
276 memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
277 job->width * job->height / 4 );
278 memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
279 job->height / 4, job->width * job->height / 4 );
282 if( in->new_chap && job->chapter_markers )
284 /* chapters have to start with an IDR frame so request that this
285 frame be coded as IDR. Since there may be up to 16 frames
286 currently buffered in the encoder remember the timestamp so
287 when this frame finally pops out of the encoder we'll mark
288 its buffer as the start of a chapter. */
289 pv->pic_in.i_type = X264_TYPE_IDR;
290 if( pv->next_chap == 0 )
292 pv->next_chap = in->start;
294 /* don't let 'work_loop' put a chapter mark on the wrong buffer */
299 pv->pic_in.i_type = X264_TYPE_AUTO;
301 pv->pic_in.i_qpplus1 = 0;
303 // Remember current PTS value, use as DTS later
304 pv->dts_start[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->start;
305 pv->dts_stop[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->stop;
306 pv->dts_write_index++;
308 /* Feed the input DTS to x264 so it can figure out proper output PTS */
309 pv->pic_in.i_pts = in->start;
311 x264_encoder_encode( pv->x264, &nal, &i_nal,
312 &pv->pic_in, &pic_out );
316 x264_encoder_encode( pv->x264, &nal, &i_nal,
318 /* No more delayed B frames */
326 /* Since we output at least one more frame, drop another empty
327 one onto our input fifo. We'll keep doing this automatically
328 until we stop getting frames out of the encoder. */
329 hb_fifo_push(w->fifo_in, hb_buffer_init(0));
335 /* Should be way too large */
336 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
338 buf->start = in->start;
339 buf->stop = in->stop;
342 int64_t dts_start, dts_stop;
344 /* Get next DTS value to use */
345 dts_start = pv->dts_start[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
346 dts_stop = pv->dts_stop[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
347 pv->dts_read_index++;
349 for( i = 0; i < i_nal; i++ )
353 data = buf->alloc - buf->size;
354 if( ( size = x264_nal_encode( buf->data + buf->size, &data,
360 if( job->mux & HB_MUX_AVI )
362 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
364 buf->frametype = HB_FRAME_KEY;
371 switch( buf->data[buf->size+4] & 0x1f )
379 /* H.264 in mp4 (stolen from mp4creator) */
380 buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
381 buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
382 buf->data[buf->size+2] = ( ( size - 4 ) >> 8 ) & 0xFF;
383 buf->data[buf->size+3] = ( ( size - 4 ) >> 0 ) & 0xFF;
384 switch( pic_out.i_type )
386 /* Decide what type of frame we have. */
388 buf->frametype = HB_FRAME_IDR;
389 /* if we have a chapter marker pending and this
390 frame's presentation time stamp is at or after
391 the marker's time stamp, use this as the
393 if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
400 buf->frametype = HB_FRAME_I;
403 buf->frametype = HB_FRAME_P;
406 buf->frametype = HB_FRAME_B;
408 /* This is for b-pyramid, which has reference b-frames
409 However, it doesn't seem to ever be used... */
411 buf->frametype = HB_FRAME_BREF;
413 /* If it isn't the above, what type of frame is it?? */
419 /* Store the output presentation time stamp
420 from x264 for use by muxmp4 in off-setting
421 b-frames with the CTTS atom.
422 For now, just add 1000000 to the offset so that the
423 value is pretty much guaranteed to be positive. The
424 muxing code will minimize the renderOffset at the end. */
426 buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
428 /* Send out the next dts values */
429 buf->start = dts_start;
430 buf->stop = dts_stop;