OSDN Git Service

fa41a5f78733b656e77136a9b8d8ab1c9ed4ecd0
[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 #define DTS_BUFFER_SIZE 32 
27
28 struct hb_work_private_s
29 {
30     hb_job_t       * job;
31     x264_t         * x264;
32     x264_picture_t   pic_in;
33
34     // Internal queue of DTS start/stop values.
35     int64_t        dts_start[DTS_BUFFER_SIZE];
36     int64_t        dts_stop[DTS_BUFFER_SIZE];
37
38     int64_t        dts_write_index;
39     int64_t        dts_read_index;
40     int64_t        next_chap;
41
42     char             filename[1024];
43 };
44
45 /***********************************************************************
46  * hb_work_encx264_init
47  ***********************************************************************
48  *
49  **********************************************************************/
50 int encx264Init( hb_work_object_t * w, hb_job_t * job )
51 {
52     x264_param_t       param;
53     x264_nal_t       * nal;
54     int                nal_count;
55
56     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
57     w->private_data = pv;
58
59     pv->job = job;
60
61     memset( pv->filename, 0, 1024 );
62     hb_get_tempory_filename( job->h, pv->filename, "x264.log" );
63
64     x264_param_default( &param );
65
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     
72     if (job->vrate_base != 1080000)
73     {
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);        
79     }
80     
81     param.i_log_level  = X264_LOG_INFO;
82     if( job->h264_level )
83     {
84         param.b_cabac     = 0;
85         param.i_level_idc = job->h264_level;
86         hb_log( "encx264: encoding at level %i",
87                 param.i_level_idc );
88     }
89
90     /* Slightly faster with minimal quality lost */
91     param.analyse.i_subpel_refine = 4;
92
93     /*
94         This section passes the string x264opts to libx264 for parsing into 
95         parameter names and values.
96
97         The string is set up like this:
98         option1=value1:option2=value 2
99
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.
103
104         This is all based on the universal x264 option handling Loren
105         Merritt implemented in the Mplayer/Mencoder project.
106      */
107
108     if( job->x264opts != NULL && *job->x264opts != '\0' )
109     {
110         char *x264opts, *x264opts_start;
111
112         x264opts = x264opts_start = strdup(job->x264opts);
113
114         while( x264opts_start && *x264opts )
115         {
116             char *name = x264opts;
117             char *value;
118             int ret;
119
120             x264opts += strcspn( x264opts, ":" );
121             if( *x264opts )
122             {
123                 *x264opts = 0;
124                 x264opts++;
125             }
126
127             value = strchr( name, '=' );
128             if( value )
129             {
130                 *value = 0;
131                 value++;
132             }
133
134             /*
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.
140              */
141
142             if( !( strcmp( name, "bframes" ) ) )
143             {
144                 if( atoi( value ) > 0 )
145                 {
146                     job->areBframes = 1;
147                 }
148             }
149
150             /* Note b-pyramid here, so the initial delay can be doubled */
151             if( !( strcmp( name, "b-pyramid" ) ) )
152             {
153                 if( value != NULL )
154                 {
155                     if( atoi( value ) > 0 )
156                     {
157                         job->areBframes = 2;
158                     }
159                 }
160                 else
161                 {
162                     job->areBframes = 2;
163                 }
164             }
165
166             /* Here's where the strings are passed to libx264 for parsing. */
167             ret = x264_param_parse( &param, name, value );
168
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)" );
174         }
175         free(x264opts_start);
176     }
177
178
179     if( job->pixel_ratio )
180     {
181         param.vui.i_sar_width = job->pixel_aspect_width;
182         param.vui.i_sar_height = job->pixel_aspect_height;
183
184         hb_log( "encx264: encoding with stored aspect %d/%d",
185                 param.vui.i_sar_width, param.vui.i_sar_height );
186     }
187
188
189     if( job->vquality >= 0.0 && job->vquality <= 1.0 )
190     {
191         switch( job->crf )
192         {
193             case 1:
194                 /*Constant RF*/
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 );
199                 break;
200
201             case 0:
202                 /*Constant QP*/
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 );
207                 break;
208         }
209     }
210     else
211     {
212         /* Rate control */
213         param.rc.i_rc_method = X264_RC_ABR;
214         param.rc.i_bitrate = job->vbitrate;
215         switch( job->pass )
216         {
217             case 1:
218                 param.rc.b_stat_write  = 1;
219                 param.rc.psz_stat_out = pv->filename;
220                 break;
221             case 2:
222                 param.rc.b_stat_read = 1;
223                 param.rc.psz_stat_in = pv->filename;
224                 break;
225         }
226     }
227
228     hb_log( "encx264: opening libx264 (pass %d)", job->pass );
229     pv->x264 = x264_encoder_open( &param );
230
231     x264_encoder_headers( pv->x264, &nal, &nal_count );
232
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 );
237
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 );
242
243     x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
244             job->width, job->height );
245
246     pv->dts_write_index = 0;
247     pv->dts_read_index = 0;
248     pv->next_chap = 0;
249
250     return 0;
251 }
252
253 void encx264Close( hb_work_object_t * w )
254 {
255     hb_work_private_t * pv = w->private_data;
256     x264_picture_clean( &pv->pic_in );
257     x264_encoder_close( pv->x264 );
258     free( pv );
259     w->private_data = NULL;
260
261     /* TODO */
262 }
263
264 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
265                   hb_buffer_t ** buf_out )
266 {
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;
271     int           i_nal;
272     x264_nal_t  * nal;
273     int i;
274
275     if( in->data )
276     {
277         /* XXX avoid this memcpy ? */
278         memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
279         if( job->grayscale )
280         {
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 );
284         }
285         else
286         {
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 );
291         }
292
293         if( in->new_chap && job->chapter_markers )
294         {
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 )
302             {
303                 pv->next_chap = in->start;
304             }
305             /* don't let 'work_loop' put a chapter mark on the wrong buffer */
306             in->new_chap = 0;
307         }
308         else
309         {
310             pv->pic_in.i_type = X264_TYPE_AUTO;
311         }
312         pv->pic_in.i_qpplus1 = 0;
313
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++;
318
319         /* Feed the input DTS to x264 so it can figure out proper output PTS */
320         pv->pic_in.i_pts = in->start;
321
322         x264_encoder_encode( pv->x264, &nal, &i_nal,
323                              &pv->pic_in, &pic_out );        
324     }
325     else
326     {
327         x264_encoder_encode( pv->x264, &nal, &i_nal,
328                              NULL, &pic_out );
329         /* No more delayed B frames */
330         if( i_nal == 0 )
331         {
332             *buf_out = NULL;
333             return HB_WORK_DONE;
334         }
335         else
336         {
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));
341         }
342     }
343
344     if( i_nal )
345     {
346         /* Should be way too large */
347         buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
348         buf->size  = 0;
349         buf->start = in->start;
350         buf->stop  = in->stop;
351         buf->frametype   = 0;
352
353         int64_t dts_start, dts_stop;
354
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++;
359
360         for( i = 0; i < i_nal; i++ )
361         {
362             int size, data;
363
364             data = buf->alloc - buf->size;
365             if( ( size = x264_nal_encode( buf->data + buf->size, &data,
366                                           1, &nal[i] ) ) < 1 )
367             {
368                 continue;
369             }
370
371             if( job->mux & HB_MUX_AVI )
372             {
373                 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
374                 {
375                     buf->frametype = HB_FRAME_KEY;
376                 }
377                 buf->size += size;
378                 continue;
379             }
380
381             /* H.264 in .mp4 */
382             switch( buf->data[buf->size+4] & 0x1f )
383             {
384                 case 0x7:
385                 case 0x8:
386                     /* SPS, PPS */
387                     break;
388
389                 default:
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 )
396                     {
397                     /*  Decide what type of frame we have. */
398                         case X264_TYPE_IDR:
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
403                                chapter start. */
404                             if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
405                             {
406                                 pv->next_chap = 0;
407                                 buf->new_chap = 1;
408                             }
409                             break;
410                         case X264_TYPE_I:
411                             buf->frametype = HB_FRAME_I;
412                             break;
413                         case X264_TYPE_P:
414                             buf->frametype = HB_FRAME_P;
415                             break;
416                         case X264_TYPE_B:
417                             buf->frametype = HB_FRAME_B;
418                             break;
419                     /*  This is for b-pyramid, which has reference b-frames
420                         However, it doesn't seem to ever be used... */
421                         case X264_TYPE_BREF:
422                             buf->frametype = HB_FRAME_BREF;
423                             break;
424                     /*  If it isn't the above, what type of frame is it?? */
425                         default:
426                             buf->frametype = 0;
427                     }
428
429
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. */
436
437                     buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
438
439                     /* Send out the next dts values */
440                     buf->start = dts_start;
441                     buf->stop  = dts_stop;
442
443                     buf->size += size;
444             }
445         }
446     }
447
448     else
449         buf = NULL;
450
451     *buf_out = buf;
452
453     return HB_WORK_OK;
454 }
455
456