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 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;
241 void encx264Close( hb_work_object_t * w )
243 hb_work_private_t * pv = w->private_data;
244 x264_picture_clean( &pv->pic_in );
245 x264_encoder_close( pv->x264 );
247 w->private_data = NULL;
252 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
253 hb_buffer_t ** buf_out )
255 hb_work_private_t * pv = w->private_data;
256 hb_job_t * job = pv->job;
257 hb_buffer_t * in = *buf_in, * buf;
258 x264_picture_t pic_out;
265 /* XXX avoid this memcpy ? */
266 memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
269 /* XXX x264 has currently no option for grayscale encoding */
270 memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
271 memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
275 memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
276 job->width * job->height / 4 );
277 memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
278 job->height / 4, job->width * job->height / 4 );
281 if( in->new_chap && job->chapter_markers )
283 /* chapters have to start with an IDR frame so request that this
284 frame be coded as IDR. Since there may be up to 16 frames
285 currently buffered in the encoder remember the timestamp so
286 when this frame finally pops out of the encoder we'll mark
287 its buffer as the start of a chapter. */
288 pv->pic_in.i_type = X264_TYPE_IDR;
289 if( pv->next_chap == 0 )
291 pv->next_chap = in->start;
293 /* don't let 'work_loop' put a chapter mark on the wrong buffer */
298 pv->pic_in.i_type = X264_TYPE_AUTO;
300 pv->pic_in.i_qpplus1 = 0;
302 // Remember current PTS value, use as DTS later
303 pv->dts_start[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->start;
304 pv->dts_stop[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->stop;
305 pv->dts_write_index++;
307 /* Feed the input DTS to x264 so it can figure out proper output PTS */
308 pv->pic_in.i_pts = in->start;
310 x264_encoder_encode( pv->x264, &nal, &i_nal,
311 &pv->pic_in, &pic_out );
315 x264_encoder_encode( pv->x264, &nal, &i_nal,
317 /* No more delayed B frames */
325 /* Since we output at least one more frame, drop another empty
326 one onto our input fifo. We'll keep doing this automatically
327 until we stop getting frames out of the encoder. */
328 hb_fifo_push(w->fifo_in, hb_buffer_init(0));
334 /* Should be way too large */
335 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
337 buf->start = in->start;
338 buf->stop = in->stop;
341 int64_t dts_start, dts_stop;
343 /* Get next DTS value to use */
344 dts_start = pv->dts_start[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
345 dts_stop = pv->dts_stop[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
346 pv->dts_read_index++;
348 for( i = 0; i < i_nal; i++ )
352 data = buf->alloc - buf->size;
353 if( ( size = x264_nal_encode( buf->data + buf->size, &data,
359 if( job->mux & HB_MUX_AVI )
361 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
363 buf->frametype = HB_FRAME_KEY;
370 switch( buf->data[buf->size+4] & 0x1f )
378 /* H.264 in mp4 (stolen from mp4creator) */
379 buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
380 buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
381 buf->data[buf->size+2] = ( ( size - 4 ) >> 8 ) & 0xFF;
382 buf->data[buf->size+3] = ( ( size - 4 ) >> 0 ) & 0xFF;
383 switch( pic_out.i_type )
385 /* Decide what type of frame we have. */
387 buf->frametype = HB_FRAME_IDR;
388 /* if we have a chapter marker pending and this
389 frame's presentation time stamp is at or after
390 the marker's time stamp, use this as the
392 if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
399 buf->frametype = HB_FRAME_I;
402 buf->frametype = HB_FRAME_P;
405 buf->frametype = HB_FRAME_B;
407 /* This is for b-pyramid, which has reference b-frames
408 However, it doesn't seem to ever be used... */
410 buf->frametype = HB_FRAME_BREF;
412 /* If it isn't the above, what type of frame is it?? */
418 /* Store the output presentation time stamp
419 from x264 for use by muxmp4 in off-setting
420 b-frames with the CTTS atom.
421 For now, just add 1000000 to the offset so that the
422 value is pretty much guaranteed to be positive. The
423 muxing code will minimize the renderOffset at the end. */
425 buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
427 /* Send out the next dts values */
428 buf->start = dts_start;
429 buf->stop = dts_stop;