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 #define DTS_BUFFER_SIZE 32
28 struct hb_work_private_s
32 x264_picture_t pic_in;
34 // Internal queue of DTS start/stop values.
35 int64_t dts_start[DTS_BUFFER_SIZE];
36 int64_t dts_stop[DTS_BUFFER_SIZE];
38 int64_t dts_write_index;
39 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;
72 if (job->vrate_base != 1080000)
74 /* If the fps isn't 25, adjust the key intervals. Add 1 because
75 we want 24, not 23 with a truncated remainder. */
76 param.i_keyint_min = (job->vrate / job->vrate_base) + 1;
77 param.i_keyint_max = (10 * job->vrate / job->vrate_base) + 1;
78 hb_log("encx264: keyint-min: %i, keyint-max: %i", param.i_keyint_min, param.i_keyint_max);
81 param.i_log_level = X264_LOG_INFO;
85 param.i_level_idc = job->h264_level;
86 hb_log( "encx264: encoding at level %i",
90 /* Slightly faster with minimal quality lost */
91 param.analyse.i_subpel_refine = 4;
94 This section passes the string x264opts to libx264 for parsing into
95 parameter names and values.
97 The string is set up like this:
98 option1=value1:option2=value 2
100 So, you have to iterate through based on the colons, and then put
101 the left side of the equals sign in "name" and the right side into
102 "value." Then you hand those strings off to x264 for interpretation.
104 This is all based on the universal x264 option handling Loren
105 Merritt implemented in the Mplayer/Mencoder project.
108 if( job->x264opts != NULL && *job->x264opts != '\0' )
110 char *x264opts, *x264opts_start;
112 x264opts = x264opts_start = strdup(job->x264opts);
114 while( x264opts_start && *x264opts )
116 char *name = x264opts;
120 x264opts += strcspn( x264opts, ":" );
127 value = strchr( name, '=' );
135 When B-frames are enabled, the max frame count increments
136 by 1 (regardless of the number of B-frames). If you don't
137 change the duration of the video track when you mux, libmp4
138 barfs. So, check if the x264opts are using B-frames, and
139 when they are, set the boolean job->areBframes as true.
142 if( !( strcmp( name, "bframes" ) ) )
144 if( atoi( value ) > 0 )
150 /* Note b-pyramid here, so the initial delay can be doubled */
151 if( !( strcmp( name, "b-pyramid" ) ) )
155 if( atoi( value ) > 0 )
166 /* Here's where the strings are passed to libx264 for parsing. */
167 ret = x264_param_parse( ¶m, name, value );
169 /* Let x264 sanity check the options for us*/
170 if( ret == X264_PARAM_BAD_NAME )
171 hb_log( "x264 options: Unknown suboption %s", name );
172 if( ret == X264_PARAM_BAD_VALUE )
173 hb_log( "x264 options: Bad argument %s=%s", name, value ? value : "(null)" );
175 free(x264opts_start);
179 if( job->pixel_ratio )
181 param.vui.i_sar_width = job->pixel_aspect_width;
182 param.vui.i_sar_height = job->pixel_aspect_height;
184 hb_log( "encx264: encoding with stored aspect %d/%d",
185 param.vui.i_sar_width, param.vui.i_sar_height );
189 if( job->vquality >= 0.0 && job->vquality <= 1.0 )
195 param.rc.i_rc_method = X264_RC_CRF;
196 param.rc.f_rf_constant = 51 - job->vquality * 51;
197 hb_log( "encx264: Encoding at constant RF %f",
198 param.rc.f_rf_constant );
203 param.rc.i_rc_method = X264_RC_CQP;
204 param.rc.i_qp_constant = 51 - job->vquality * 51;
205 hb_log( "encx264: encoding at constant QP %d",
206 param.rc.i_qp_constant );
213 param.rc.i_rc_method = X264_RC_ABR;
214 param.rc.i_bitrate = job->vbitrate;
218 param.rc.b_stat_write = 1;
219 param.rc.psz_stat_out = pv->filename;
222 param.rc.b_stat_read = 1;
223 param.rc.psz_stat_in = pv->filename;
228 hb_log( "encx264: opening libx264 (pass %d)", job->pass );
229 pv->x264 = x264_encoder_open( ¶m );
231 x264_encoder_headers( pv->x264, &nal, &nal_count );
233 /* Sequence Parameter Set */
234 w->config->h264.sps_length = 1 + nal[1].i_payload;
235 w->config->h264.sps[0] = 0x67;
236 memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
238 /* Picture Parameter Set */
239 w->config->h264.pps_length = 1 + nal[2].i_payload;
240 w->config->h264.pps[0] = 0x68;
241 memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
243 x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
244 job->width, job->height );
246 pv->dts_write_index = 0;
247 pv->dts_read_index = 0;
253 void encx264Close( hb_work_object_t * w )
255 hb_work_private_t * pv = w->private_data;
256 x264_picture_clean( &pv->pic_in );
257 x264_encoder_close( pv->x264 );
259 w->private_data = NULL;
264 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
265 hb_buffer_t ** buf_out )
267 hb_work_private_t * pv = w->private_data;
268 hb_job_t * job = pv->job;
269 hb_buffer_t * in = *buf_in, * buf;
270 x264_picture_t pic_out;
277 /* XXX avoid this memcpy ? */
278 memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
281 /* XXX x264 has currently no option for grayscale encoding */
282 memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
283 memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
287 memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
288 job->width * job->height / 4 );
289 memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
290 job->height / 4, job->width * job->height / 4 );
293 if( in->new_chap && job->chapter_markers )
295 /* chapters have to start with an IDR frame so request that this
296 frame be coded as IDR. Since there may be up to 16 frames
297 currently buffered in the encoder remember the timestamp so
298 when this frame finally pops out of the encoder we'll mark
299 its buffer as the start of a chapter. */
300 pv->pic_in.i_type = X264_TYPE_IDR;
301 if( pv->next_chap == 0 )
303 pv->next_chap = in->start;
305 /* don't let 'work_loop' put a chapter mark on the wrong buffer */
310 pv->pic_in.i_type = X264_TYPE_AUTO;
312 pv->pic_in.i_qpplus1 = 0;
314 // Remember current PTS value, use as DTS later
315 pv->dts_start[pv->dts_write_index & (DTS_BUFFER_SIZE-1)] = in->start;
316 pv->dts_stop[pv->dts_write_index & (DTS_BUFFER_SIZE-1)] = in->stop;
317 pv->dts_write_index++;
319 /* Feed the input DTS to x264 so it can figure out proper output PTS */
320 pv->pic_in.i_pts = in->start;
322 x264_encoder_encode( pv->x264, &nal, &i_nal,
323 &pv->pic_in, &pic_out );
327 x264_encoder_encode( pv->x264, &nal, &i_nal,
329 /* No more delayed B frames */
337 /* Since we output at least one more frame, drop another empty
338 one onto our input fifo. We'll keep doing this automatically
339 until we stop getting frames out of the encoder. */
340 hb_fifo_push(w->fifo_in, hb_buffer_init(0));
346 /* Should be way too large */
347 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
349 buf->start = in->start;
350 buf->stop = in->stop;
353 int64_t dts_start, dts_stop;
355 /* Get next DTS value to use */
356 dts_start = pv->dts_start[pv->dts_read_index & (DTS_BUFFER_SIZE-1)];
357 dts_stop = pv->dts_stop[pv->dts_read_index & (DTS_BUFFER_SIZE-1)];
358 pv->dts_read_index++;
360 for( i = 0; i < i_nal; i++ )
364 data = buf->alloc - buf->size;
365 if( ( size = x264_nal_encode( buf->data + buf->size, &data,
371 if( job->mux & HB_MUX_AVI )
373 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
375 buf->frametype = HB_FRAME_KEY;
382 switch( buf->data[buf->size+4] & 0x1f )
390 /* H.264 in mp4 (stolen from mp4creator) */
391 buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
392 buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
393 buf->data[buf->size+2] = ( ( size - 4 ) >> 8 ) & 0xFF;
394 buf->data[buf->size+3] = ( ( size - 4 ) >> 0 ) & 0xFF;
395 switch( pic_out.i_type )
397 /* Decide what type of frame we have. */
399 buf->frametype = HB_FRAME_IDR;
400 /* if we have a chapter marker pending and this
401 frame's presentation time stamp is at or after
402 the marker's time stamp, use this as the
404 if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
411 buf->frametype = HB_FRAME_I;
414 buf->frametype = HB_FRAME_P;
417 buf->frametype = HB_FRAME_B;
419 /* This is for b-pyramid, which has reference b-frames
420 However, it doesn't seem to ever be used... */
422 buf->frametype = HB_FRAME_BREF;
424 /* If it isn't the above, what type of frame is it?? */
430 /* Store the output presentation time stamp
431 from x264 for use by muxmp4 in off-setting
432 b-frames with the CTTS atom.
433 For now, just add 1000000 to the offset so that the
434 value is pretty much guaranteed to be positive. The
435 muxing code will minimize the renderOffset at the end. */
437 buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
439 /* Send out the next dts values */
440 buf->start = dts_start;
441 buf->stop = dts_stop;