OSDN Git Service

95922d50449cafb87d5dfc4dd6d66d69a55792dc
[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     char *x264opts = job->x264opts;
101     if( x264opts != NULL && *x264opts != '\0' )
102     {
103         while( *x264opts )
104         {
105             char *name = x264opts;
106             char *value;
107             int ret;
108
109             x264opts += strcspn( x264opts, ":" );
110             if( *x264opts )
111             {
112                 *x264opts = 0;
113                 x264opts++;
114             }
115
116             value = strchr( name, '=' );
117             if( value )
118             {
119                 *value = 0;
120                 value++;
121             }
122
123             /*
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.
129              */
130
131             if( !( strcmp( name, "bframes" ) ) )
132             {
133                 if( atoi( value ) > 0 )
134                 {
135                     job->areBframes = 1;
136                 }
137             }
138
139             /* Note b-pyramid here, so the initial delay can be doubled */
140             if( !( strcmp( name, "b-pyramid" ) ) )
141             {
142                 if( value != NULL )
143                 {
144                     if( atoi( value ) > 0 )
145                     {
146                         job->areBframes = 2;
147                     }
148                 }
149                 else
150                 {
151                     job->areBframes = 2;
152                 }
153             }
154
155             /* Here's where the strings are passed to libx264 for parsing. */
156             ret = x264_param_parse( &param, name, value );
157
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)" );
163         }
164     }
165
166
167     if( job->pixel_ratio )
168     {
169         param.vui.i_sar_width = job->pixel_aspect_width;
170         param.vui.i_sar_height = job->pixel_aspect_height;
171
172         hb_log( "encx264: encoding with stored aspect %d/%d",
173                 param.vui.i_sar_width, param.vui.i_sar_height );
174     }
175
176
177     if( job->vquality >= 0.0 && job->vquality <= 1.0 )
178     {
179         switch( job->crf )
180         {
181             case 1:
182                 /*Constant RF*/
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 );
187                 break;
188
189             case 0:
190                 /*Constant QP*/
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 );
195                 break;
196         }
197     }
198     else
199     {
200         /* Rate control */
201         param.rc.i_rc_method = X264_RC_ABR;
202         param.rc.i_bitrate = job->vbitrate;
203         switch( job->pass )
204         {
205             case 1:
206                 param.rc.b_stat_write  = 1;
207                 param.rc.psz_stat_out = pv->filename;
208                 break;
209             case 2:
210                 param.rc.b_stat_read = 1;
211                 param.rc.psz_stat_in = pv->filename;
212                 break;
213         }
214     }
215
216     hb_log( "encx264: opening libx264 (pass %d)", job->pass );
217     pv->x264 = x264_encoder_open( &param );
218
219     x264_encoder_headers( pv->x264, &nal, &nal_count );
220
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 );
225
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 );
230
231     x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
232             job->width, job->height );
233
234     pv->dts_write_index = 0;
235     pv->dts_read_index = 0;
236     pv->next_chap = 0;
237
238     return 0;
239 }
240
241 void encx264Close( hb_work_object_t * w )
242 {
243     hb_work_private_t * pv = w->private_data;
244     x264_picture_clean( &pv->pic_in );
245     x264_encoder_close( pv->x264 );
246     free( pv );
247     w->private_data = NULL;
248
249     /* TODO */
250 }
251
252 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
253                   hb_buffer_t ** buf_out )
254 {
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;
259     int           i_nal;
260     x264_nal_t  * nal;
261     int i;
262
263     if( in->data )
264     {
265         /* XXX avoid this memcpy ? */
266         memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
267         if( job->grayscale )
268         {
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 );
272         }
273         else
274         {
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 );
279         }
280
281         if( in->new_chap && job->chapter_markers )
282         {
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 )
290             {
291                 pv->next_chap = in->start;
292             }
293             /* don't let 'work_loop' put a chapter mark on the wrong buffer */
294             in->new_chap = 0;
295         }
296         else
297         {
298             pv->pic_in.i_type = X264_TYPE_AUTO;
299         }
300         pv->pic_in.i_qpplus1 = 0;
301
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++;
306
307         /* Feed the input DTS to x264 so it can figure out proper output PTS */
308         pv->pic_in.i_pts = in->start;
309
310         x264_encoder_encode( pv->x264, &nal, &i_nal,
311                              &pv->pic_in, &pic_out );        
312     }
313     else
314     {
315         x264_encoder_encode( pv->x264, &nal, &i_nal,
316                              NULL, &pic_out );
317         /* No more delayed B frames */
318         if( i_nal == 0 )
319         {
320             *buf_out = NULL;
321             return HB_WORK_DONE;
322         }
323         else
324         {
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));
329         }
330     }
331
332     if( i_nal )
333     {
334         /* Should be way too large */
335         buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
336         buf->size  = 0;
337         buf->start = in->start;
338         buf->stop  = in->stop;
339         buf->frametype   = 0;
340
341         int64_t dts_start, dts_stop;
342
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++;
347
348         for( i = 0; i < i_nal; i++ )
349         {
350             int size, data;
351
352             data = buf->alloc - buf->size;
353             if( ( size = x264_nal_encode( buf->data + buf->size, &data,
354                                           1, &nal[i] ) ) < 1 )
355             {
356                 continue;
357             }
358
359             if( job->mux & HB_MUX_AVI )
360             {
361                 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
362                 {
363                     buf->frametype = HB_FRAME_KEY;
364                 }
365                 buf->size += size;
366                 continue;
367             }
368
369             /* H.264 in .mp4 */
370             switch( buf->data[buf->size+4] & 0x1f )
371             {
372                 case 0x7:
373                 case 0x8:
374                     /* SPS, PPS */
375                     break;
376
377                 default:
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 )
384                     {
385                     /*  Decide what type of frame we have. */
386                         case X264_TYPE_IDR:
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
391                                chapter start. */
392                             if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
393                             {
394                                 pv->next_chap = 0;
395                                 buf->new_chap = 1;
396                             }
397                             break;
398                         case X264_TYPE_I:
399                             buf->frametype = HB_FRAME_I;
400                             break;
401                         case X264_TYPE_P:
402                             buf->frametype = HB_FRAME_P;
403                             break;
404                         case X264_TYPE_B:
405                             buf->frametype = HB_FRAME_B;
406                             break;
407                     /*  This is for b-pyramid, which has reference b-frames
408                         However, it doesn't seem to ever be used... */
409                         case X264_TYPE_BREF:
410                             buf->frametype = HB_FRAME_BREF;
411                             break;
412                     /*  If it isn't the above, what type of frame is it?? */
413                         default:
414                             buf->frametype = 0;
415                     }
416
417
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. */
424
425                     buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
426
427                     /* Send out the next dts values */
428                     buf->start = dts_start;
429                     buf->stop  = dts_stop;
430
431                     buf->size += size;
432             }
433         }
434     }
435
436     else
437         buf = NULL;
438
439     *buf_out = buf;
440
441     return HB_WORK_OK;
442 }
443
444