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;
71 param.i_keyint_max = 20 * job->vrate / job->vrate_base;
72 param.i_log_level = X264_LOG_INFO;
76 param.i_level_idc = job->h264_level;
77 hb_log( "encx264: encoding at level %i",
81 /* Slightly faster with minimal quality lost */
82 param.analyse.i_subpel_refine = 4;
85 This section passes the string x264opts to libx264 for parsing into
86 parameter names and values.
88 The string is set up like this:
89 option1=value1:option2=value 2
91 So, you have to iterate through based on the colons, and then put
92 the left side of the equals sign in "name" and the right side into
93 "value." Then you hand those strings off to x264 for interpretation.
95 This is all based on the universal x264 option handling Loren
96 Merritt implemented in the Mplayer/Mencoder project.
99 if( job->x264opts != NULL && *job->x264opts != '\0' )
101 char *x264opts, *x264opts_start;
103 x264opts = x264opts_start = strdup(job->x264opts);
105 while( x264opts_start && *x264opts )
107 char *name = x264opts;
111 x264opts += strcspn( x264opts, ":" );
118 value = strchr( name, '=' );
126 When B-frames are enabled, the max frame count increments
127 by 1 (regardless of the number of B-frames). If you don't
128 change the duration of the video track when you mux, libmp4
129 barfs. So, check if the x264opts are using B-frames, and
130 when they are, set the boolean job->areBframes as true.
133 if( !( strcmp( name, "bframes" ) ) )
135 if( atoi( value ) > 0 )
141 /* Note b-pyramid here, so the initial delay can be doubled */
142 if( !( strcmp( name, "b-pyramid" ) ) )
146 if( atoi( value ) > 0 )
157 /* Here's where the strings are passed to libx264 for parsing. */
158 ret = x264_param_parse( ¶m, name, value );
160 /* Let x264 sanity check the options for us*/
161 if( ret == X264_PARAM_BAD_NAME )
162 hb_log( "x264 options: Unknown suboption %s", name );
163 if( ret == X264_PARAM_BAD_VALUE )
164 hb_log( "x264 options: Bad argument %s=%s", name, value ? value : "(null)" );
166 free(x264opts_start);
170 if( job->pixel_ratio )
172 param.vui.i_sar_width = job->pixel_aspect_width;
173 param.vui.i_sar_height = job->pixel_aspect_height;
175 hb_log( "encx264: encoding with stored aspect %d/%d",
176 param.vui.i_sar_width, param.vui.i_sar_height );
180 if( job->vquality >= 0.0 && job->vquality <= 1.0 )
186 param.rc.i_rc_method = X264_RC_CRF;
187 param.rc.f_rf_constant = 51 - job->vquality * 51;
188 hb_log( "encx264: Encoding at constant RF %f",
189 param.rc.f_rf_constant );
194 param.rc.i_rc_method = X264_RC_CQP;
195 param.rc.i_qp_constant = 51 - job->vquality * 51;
196 hb_log( "encx264: encoding at constant QP %d",
197 param.rc.i_qp_constant );
204 param.rc.i_rc_method = X264_RC_ABR;
205 param.rc.i_bitrate = job->vbitrate;
209 param.rc.b_stat_write = 1;
210 param.rc.psz_stat_out = pv->filename;
213 param.rc.b_stat_read = 1;
214 param.rc.psz_stat_in = pv->filename;
219 hb_log( "encx264: opening libx264 (pass %d)", job->pass );
220 pv->x264 = x264_encoder_open( ¶m );
222 x264_encoder_headers( pv->x264, &nal, &nal_count );
224 /* Sequence Parameter Set */
225 w->config->h264.sps_length = 1 + nal[1].i_payload;
226 w->config->h264.sps[0] = 0x67;
227 memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
229 /* Picture Parameter Set */
230 w->config->h264.pps_length = 1 + nal[2].i_payload;
231 w->config->h264.pps[0] = 0x68;
232 memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
234 x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
235 job->width, job->height );
237 pv->dts_write_index = 0;
238 pv->dts_read_index = 0;
244 void encx264Close( hb_work_object_t * w )
246 hb_work_private_t * pv = w->private_data;
247 x264_picture_clean( &pv->pic_in );
248 x264_encoder_close( pv->x264 );
250 w->private_data = NULL;
255 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
256 hb_buffer_t ** buf_out )
258 hb_work_private_t * pv = w->private_data;
259 hb_job_t * job = pv->job;
260 hb_buffer_t * in = *buf_in, * buf;
261 x264_picture_t pic_out;
268 /* XXX avoid this memcpy ? */
269 memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
272 /* XXX x264 has currently no option for grayscale encoding */
273 memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
274 memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
278 memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
279 job->width * job->height / 4 );
280 memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
281 job->height / 4, job->width * job->height / 4 );
284 if( in->new_chap && job->chapter_markers )
286 /* chapters have to start with an IDR frame so request that this
287 frame be coded as IDR. Since there may be up to 16 frames
288 currently buffered in the encoder remember the timestamp so
289 when this frame finally pops out of the encoder we'll mark
290 its buffer as the start of a chapter. */
291 pv->pic_in.i_type = X264_TYPE_IDR;
292 if( pv->next_chap == 0 )
294 pv->next_chap = in->start;
296 /* don't let 'work_loop' put a chapter mark on the wrong buffer */
301 pv->pic_in.i_type = X264_TYPE_AUTO;
303 pv->pic_in.i_qpplus1 = 0;
305 // Remember current PTS value, use as DTS later
306 pv->dts_start[pv->dts_write_index & (DTS_BUFFER_SIZE-1)] = in->start;
307 pv->dts_stop[pv->dts_write_index & (DTS_BUFFER_SIZE-1)] = in->stop;
308 pv->dts_write_index++;
310 /* Feed the input DTS to x264 so it can figure out proper output PTS */
311 pv->pic_in.i_pts = in->start;
313 x264_encoder_encode( pv->x264, &nal, &i_nal,
314 &pv->pic_in, &pic_out );
318 x264_encoder_encode( pv->x264, &nal, &i_nal,
320 /* No more delayed B frames */
328 /* Since we output at least one more frame, drop another empty
329 one onto our input fifo. We'll keep doing this automatically
330 until we stop getting frames out of the encoder. */
331 hb_fifo_push(w->fifo_in, hb_buffer_init(0));
337 /* Should be way too large */
338 buf = hb_buffer_init( 3 * job->width * job->height / 2 );
340 buf->start = in->start;
341 buf->stop = in->stop;
344 int64_t dts_start, dts_stop;
346 /* Get next DTS value to use */
347 dts_start = pv->dts_start[pv->dts_read_index & (DTS_BUFFER_SIZE-1)];
348 dts_stop = pv->dts_stop[pv->dts_read_index & (DTS_BUFFER_SIZE-1)];
349 pv->dts_read_index++;
351 for( i = 0; i < i_nal; i++ )
355 data = buf->alloc - buf->size;
356 if( ( size = x264_nal_encode( buf->data + buf->size, &data,
362 if( job->mux & HB_MUX_AVI )
364 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
366 buf->frametype = HB_FRAME_KEY;
373 switch( buf->data[buf->size+4] & 0x1f )
381 /* H.264 in mp4 (stolen from mp4creator) */
382 buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
383 buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
384 buf->data[buf->size+2] = ( ( size - 4 ) >> 8 ) & 0xFF;
385 buf->data[buf->size+3] = ( ( size - 4 ) >> 0 ) & 0xFF;
386 switch( pic_out.i_type )
388 /* Decide what type of frame we have. */
390 buf->frametype = HB_FRAME_IDR;
391 /* if we have a chapter marker pending and this
392 frame's presentation time stamp is at or after
393 the marker's time stamp, use this as the
395 if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
402 buf->frametype = HB_FRAME_I;
405 buf->frametype = HB_FRAME_P;
408 buf->frametype = HB_FRAME_B;
410 /* This is for b-pyramid, which has reference b-frames
411 However, it doesn't seem to ever be used... */
413 buf->frametype = HB_FRAME_BREF;
415 /* If it isn't the above, what type of frame is it?? */
421 /* Store the output presentation time stamp
422 from x264 for use by muxmp4 in off-setting
423 b-frames with the CTTS atom.
424 For now, just add 1000000 to the offset so that the
425 value is pretty much guaranteed to be positive. The
426 muxing code will minimize the renderOffset at the end. */
428 buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
430 /* Send out the next dts values */
431 buf->start = dts_start;
432 buf->stop = dts_stop;