OSDN Git Service

Don't drop subtitles when crossing PTS discontinuities by using buffer sequence numbe...
[handbrake-jp/handbrake-jp-git.git] / libhb / encx264.c
1 /* $Id: encx264.c,v 1.21 2005/11/04 13:09:41 titer Exp $
2
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. */
6
7 #include <stdarg.h>
8
9 #include "hb.h"
10
11 #include "x264.h"
12
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 * );
16
17 hb_work_object_t hb_encx264 =
18 {
19     WORK_ENCX264,
20     "H.264/AVC encoder (libx264)",
21     encx264Init,
22     encx264Work,
23     encx264Close
24 };
25
26 // 16 is probably overkill but it's also the maximum for h.264 reference frames
27 #define MAX_INFLIGHT_FRAMES 16
28
29 struct hb_work_private_s
30 {
31     hb_job_t       * job;
32     x264_t         * x264;
33     x264_picture_t   pic_in;
34
35     // Internal queue of DTS start/stop values.
36     int64_t        dts_start[MAX_INFLIGHT_FRAMES];
37     int64_t        dts_stop[MAX_INFLIGHT_FRAMES];
38
39     int64_t        dts_write_index;
40     int64_t        dts_read_index;
41     int64_t        next_chap;
42
43     char             filename[1024];
44 };
45
46 /***********************************************************************
47  * hb_work_encx264_init
48  ***********************************************************************
49  *
50  **********************************************************************/
51 int encx264Init( hb_work_object_t * w, hb_job_t * job )
52 {
53     x264_param_t       param;
54     x264_nal_t       * nal;
55     int                nal_count;
56
57     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
58     w->private_data = pv;
59
60     pv->job = job;
61
62     memset( pv->filename, 0, 1024 );
63     hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
64
65     x264_param_default( &param );
66
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;
74     if( job->h264_level )
75     {
76         param.b_cabac     = 0;
77         param.i_level_idc = job->h264_level;
78         hb_log( "encx264: encoding at level %i",
79                 param.i_level_idc );
80     }
81
82     /* Slightly faster with minimal quality lost */
83     param.analyse.i_subpel_refine = 4;
84
85     /*
86         This section passes the string x264opts to libx264 for parsing into 
87         parameter names and values.
88
89         The string is set up like this:
90         option1=value1:option2=value 2
91
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.
95
96         This is all based on the universal x264 option handling Loren
97         Merritt implemented in the Mplayer/Mencoder project.
98      */
99
100     if( job->x264opts != NULL && *job->x264opts != '\0' )
101     {
102         char *x264opts, *x264opts_start;
103
104         x264opts = x264opts_start = strdup(job->x264opts);
105
106         while( x264opts_start && *x264opts )
107         {
108             char *name = x264opts;
109             char *value;
110             int ret;
111
112             x264opts += strcspn( x264opts, ":" );
113             if( *x264opts )
114             {
115                 *x264opts = 0;
116                 x264opts++;
117             }
118
119             value = strchr( name, '=' );
120             if( value )
121             {
122                 *value = 0;
123                 value++;
124             }
125
126             /*
127                When B-frames are enabled, the max frame count increments
128                by 1 (regardless of the number of B-frames). If you don't
129                change the duration of the video track when you mux, libmp4
130                barfs.  So, check if the x264opts are using B-frames, and
131                when they are, set the boolean job->areBframes as true.
132              */
133
134             if( !( strcmp( name, "bframes" ) ) )
135             {
136                 if( atoi( value ) > 0 )
137                 {
138                     job->areBframes = 1;
139                 }
140             }
141
142             /* Note b-pyramid here, so the initial delay can be doubled */
143             if( !( strcmp( name, "b-pyramid" ) ) )
144             {
145                 if( value != NULL )
146                 {
147                     if( atoi( value ) > 0 )
148                     {
149                         job->areBframes = 2;
150                     }
151                 }
152                 else
153                 {
154                     job->areBframes = 2;
155                 }
156             }
157
158             /* Here's where the strings are passed to libx264 for parsing. */
159             ret = x264_param_parse( &param, name, value );
160
161             /*  Let x264 sanity check the options for us*/
162             if( ret == X264_PARAM_BAD_NAME )
163                 hb_log( "x264 options: Unknown suboption %s", name );
164             if( ret == X264_PARAM_BAD_VALUE )
165                 hb_log( "x264 options: Bad argument %s=%s", name, value ? value : "(null)" );
166         }
167         free(x264opts_start);
168     }
169
170
171     if( job->pixel_ratio )
172     {
173         param.vui.i_sar_width = job->pixel_aspect_width;
174         param.vui.i_sar_height = job->pixel_aspect_height;
175
176         hb_log( "encx264: encoding with stored aspect %d/%d",
177                 param.vui.i_sar_width, param.vui.i_sar_height );
178     }
179
180
181     if( job->vquality >= 0.0 && job->vquality <= 1.0 )
182     {
183         switch( job->crf )
184         {
185             case 1:
186                 /*Constant RF*/
187                 param.rc.i_rc_method = X264_RC_CRF;
188                 param.rc.f_rf_constant = 51 - job->vquality * 51;
189                 hb_log( "encx264: Encoding at constant RF %f",
190                         param.rc.f_rf_constant );
191                 break;
192
193             case 0:
194                 /*Constant QP*/
195                 param.rc.i_rc_method = X264_RC_CQP;
196                 param.rc.i_qp_constant = 51 - job->vquality * 51;
197                 hb_log( "encx264: encoding at constant QP %d",
198                         param.rc.i_qp_constant );
199                 break;
200         }
201     }
202     else
203     {
204         /* Rate control */
205         param.rc.i_rc_method = X264_RC_ABR;
206         param.rc.i_bitrate = job->vbitrate;
207         switch( job->pass )
208         {
209             case 1:
210                 param.rc.b_stat_write  = 1;
211                 param.rc.psz_stat_out = pv->filename;
212                 break;
213             case 2:
214                 param.rc.b_stat_read = 1;
215                 param.rc.psz_stat_in = pv->filename;
216                 break;
217         }
218     }
219
220     hb_log( "encx264: opening libx264 (pass %d)", job->pass );
221     pv->x264 = x264_encoder_open( &param );
222
223     x264_encoder_headers( pv->x264, &nal, &nal_count );
224
225     /* Sequence Parameter Set */
226     w->config->h264.sps_length = 1 + nal[1].i_payload;
227     w->config->h264.sps[0] = 0x67;
228     memcpy( &w->config->h264.sps[1], nal[1].p_payload, nal[1].i_payload );
229
230     /* Picture Parameter Set */
231     w->config->h264.pps_length = 1 + nal[2].i_payload;
232     w->config->h264.pps[0] = 0x68;
233     memcpy( &w->config->h264.pps[1], nal[2].p_payload, nal[2].i_payload );
234
235     x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
236             job->width, job->height );
237
238     pv->dts_write_index = 0;
239     pv->dts_read_index = 0;
240     pv->next_chap = 0;
241
242     return 0;
243 }
244
245 void encx264Close( hb_work_object_t * w )
246 {
247     hb_work_private_t * pv = w->private_data;
248     x264_picture_clean( &pv->pic_in );
249     x264_encoder_close( pv->x264 );
250     free( pv );
251     w->private_data = NULL;
252
253     /* TODO */
254 }
255
256 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
257                   hb_buffer_t ** buf_out )
258 {
259     hb_work_private_t * pv = w->private_data;
260     hb_job_t    * job = pv->job;
261     hb_buffer_t * in = *buf_in, * buf;
262     x264_picture_t   pic_out;
263     int           i_nal;
264     x264_nal_t  * nal;
265     int i;
266
267     if( in->data )
268     {
269         /* XXX avoid this memcpy ? */
270         memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
271         if( job->grayscale )
272         {
273             /* XXX x264 has currently no option for grayscale encoding */
274             memset( pv->pic_in.img.plane[1], 0x80, job->width * job->height / 4 );
275             memset( pv->pic_in.img.plane[2], 0x80, job->width * job->height / 4 );
276         }
277         else
278         {
279             memcpy( pv->pic_in.img.plane[1], in->data + job->width * job->height,
280                     job->width * job->height / 4 );
281             memcpy( pv->pic_in.img.plane[2], in->data + 5 * job->width *
282                     job->height / 4, job->width * job->height / 4 );
283         }
284
285         if( in->new_chap && job->chapter_markers )
286         {
287             /* chapters have to start with an IDR frame so request that this
288                frame be coded as IDR. Since there may be up to 16 frames
289                currently buffered in the encoder remember the timestamp so
290                when this frame finally pops out of the encoder we'll mark
291                its buffer as the start of a chapter. */
292             pv->pic_in.i_type = X264_TYPE_IDR;
293             if( pv->next_chap == 0 )
294             {
295                 pv->next_chap = in->start;
296             }
297             /* don't let 'work_loop' put a chapter mark on the wrong buffer */
298             in->new_chap = 0;
299         }
300         else
301         {
302             pv->pic_in.i_type = X264_TYPE_AUTO;
303         }
304         pv->pic_in.i_qpplus1 = 0;
305
306         // Remember current PTS value, use as DTS later
307         pv->dts_start[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)] = in->start;
308         pv->dts_stop[pv->dts_write_index & (MAX_INFLIGHT_FRAMES-1)]  = in->stop;
309         pv->dts_write_index++;
310
311         /* Feed the input DTS to x264 so it can figure out proper output PTS */
312         pv->pic_in.i_pts = in->start;
313
314         x264_encoder_encode( pv->x264, &nal, &i_nal,
315                              &pv->pic_in, &pic_out );        
316     }
317     else
318     {
319         x264_encoder_encode( pv->x264, &nal, &i_nal,
320                              NULL, &pic_out );
321         /* No more delayed B frames */
322         if( i_nal == 0 )
323         {
324             *buf_out = NULL;
325             return HB_WORK_DONE;
326         }
327         else
328         {
329         /*  Since we output at least one more frame, drop another empty
330             one onto our input fifo.  We'll keep doing this automatically
331             until we stop getting frames out of the encoder. */
332             hb_fifo_push(w->fifo_in, hb_buffer_init(0));
333         }
334     }
335
336     if( i_nal )
337     {
338         /* Should be way too large */
339         buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
340         buf->size  = 0;
341         buf->start = in->start;
342         buf->stop  = in->stop;
343         buf->frametype   = 0;
344
345         int64_t dts_start, dts_stop;
346
347         /* Get next DTS value to use */
348         dts_start = pv->dts_start[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
349         dts_stop  = pv->dts_stop[pv->dts_read_index & (MAX_INFLIGHT_FRAMES-1)];
350         pv->dts_read_index++;
351
352         for( i = 0; i < i_nal; i++ )
353         {
354             int size, data;
355
356             data = buf->alloc - buf->size;
357             if( ( size = x264_nal_encode( buf->data + buf->size, &data,
358                                           1, &nal[i] ) ) < 1 )
359             {
360                 continue;
361             }
362
363             if( job->mux & HB_MUX_AVI )
364             {
365                 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
366                 {
367                     buf->frametype = HB_FRAME_KEY;
368                 }
369                 buf->size += size;
370                 continue;
371             }
372
373             /* H.264 in .mp4 */
374             switch( buf->data[buf->size+4] & 0x1f )
375             {
376                 case 0x7:
377                 case 0x8:
378                     /* SPS, PPS */
379                     break;
380
381                 default:
382                     /* H.264 in mp4 (stolen from mp4creator) */
383                     buf->data[buf->size+0] = ( ( size - 4 ) >> 24 ) & 0xFF;
384                     buf->data[buf->size+1] = ( ( size - 4 ) >> 16 ) & 0xFF;
385                     buf->data[buf->size+2] = ( ( size - 4 ) >>  8 ) & 0xFF;
386                     buf->data[buf->size+3] = ( ( size - 4 ) >>  0 ) & 0xFF;
387                     switch( pic_out.i_type )
388                     {
389                     /*  Decide what type of frame we have. */
390                         case X264_TYPE_IDR:
391                             buf->frametype = HB_FRAME_IDR;
392                             /* if we have a chapter marker pending and this
393                                frame's presentation time stamp is at or after
394                                the marker's time stamp, use this as the
395                                chapter start. */
396                             if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
397                             {
398                                 pv->next_chap = 0;
399                                 buf->new_chap = 1;
400                             }
401                             break;
402                         case X264_TYPE_I:
403                             buf->frametype = HB_FRAME_I;
404                             break;
405                         case X264_TYPE_P:
406                             buf->frametype = HB_FRAME_P;
407                             break;
408                         case X264_TYPE_B:
409                             buf->frametype = HB_FRAME_B;
410                             break;
411                     /*  This is for b-pyramid, which has reference b-frames
412                         However, it doesn't seem to ever be used... */
413                         case X264_TYPE_BREF:
414                             buf->frametype = HB_FRAME_BREF;
415                             break;
416                     /*  If it isn't the above, what type of frame is it?? */
417                         default:
418                             buf->frametype = 0;
419                     }
420
421
422                     /* Store the output presentation time stamp
423                        from x264 for use by muxmp4 in off-setting
424                        b-frames with the CTTS atom.
425                        For now, just add 1000000 to the offset so that the
426                        value is pretty much guaranteed to be positive.  The
427                        muxing code will minimize the renderOffset at the end. */
428
429                     buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
430
431                     /* Send out the next dts values */
432                     buf->start = dts_start;
433                     buf->stop  = dts_stop;
434
435                     buf->size += size;
436             }
437         }
438     }
439
440     else
441         buf = NULL;
442
443     *buf_out = buf;
444
445     return HB_WORK_OK;
446 }
447
448