OSDN Git Service

Repeat after me, eddyg is a wally.
[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     param.i_keyint_max = 20 * job->vrate / job->vrate_base;
72     param.i_log_level  = X264_LOG_INFO;
73     if( job->h264_level )
74     {
75         param.b_cabac     = 0;
76         param.i_level_idc = job->h264_level;
77         hb_log( "encx264: encoding at level %i",
78                 param.i_level_idc );
79     }
80
81     /* Slightly faster with minimal quality lost */
82     param.analyse.i_subpel_refine = 4;
83
84     /*
85         This section passes the string x264opts to libx264 for parsing into 
86         parameter names and values.
87
88         The string is set up like this:
89         option1=value1:option2=value 2
90
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.
94
95         This is all based on the universal x264 option handling Loren
96         Merritt implemented in the Mplayer/Mencoder project.
97      */
98
99     if( job->x264opts != NULL && *job->x264opts != '\0' )
100     {
101         char *x264opts, *x264opts_start;
102
103         x264opts = x264opts_start = strdup(job->x264opts);
104
105         while( x264opts_start && *x264opts )
106         {
107             char *name = x264opts;
108             char *value;
109             int ret;
110
111             x264opts += strcspn( x264opts, ":" );
112             if( *x264opts )
113             {
114                 *x264opts = 0;
115                 x264opts++;
116             }
117
118             value = strchr( name, '=' );
119             if( value )
120             {
121                 *value = 0;
122                 value++;
123             }
124
125             /*
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.
131              */
132
133             if( !( strcmp( name, "bframes" ) ) )
134             {
135                 if( atoi( value ) > 0 )
136                 {
137                     job->areBframes = 1;
138                 }
139             }
140
141             /* Note b-pyramid here, so the initial delay can be doubled */
142             if( !( strcmp( name, "b-pyramid" ) ) )
143             {
144                 if( value != NULL )
145                 {
146                     if( atoi( value ) > 0 )
147                     {
148                         job->areBframes = 2;
149                     }
150                 }
151                 else
152                 {
153                     job->areBframes = 2;
154                 }
155             }
156
157             /* Here's where the strings are passed to libx264 for parsing. */
158             ret = x264_param_parse( &param, name, value );
159
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)" );
165         }
166         free(x264opts_start);
167     }
168
169
170     if( job->pixel_ratio )
171     {
172         param.vui.i_sar_width = job->pixel_aspect_width;
173         param.vui.i_sar_height = job->pixel_aspect_height;
174
175         hb_log( "encx264: encoding with stored aspect %d/%d",
176                 param.vui.i_sar_width, param.vui.i_sar_height );
177     }
178
179
180     if( job->vquality >= 0.0 && job->vquality <= 1.0 )
181     {
182         switch( job->crf )
183         {
184             case 1:
185                 /*Constant RF*/
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 );
190                 break;
191
192             case 0:
193                 /*Constant QP*/
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 );
198                 break;
199         }
200     }
201     else
202     {
203         /* Rate control */
204         param.rc.i_rc_method = X264_RC_ABR;
205         param.rc.i_bitrate = job->vbitrate;
206         switch( job->pass )
207         {
208             case 1:
209                 param.rc.b_stat_write  = 1;
210                 param.rc.psz_stat_out = pv->filename;
211                 break;
212             case 2:
213                 param.rc.b_stat_read = 1;
214                 param.rc.psz_stat_in = pv->filename;
215                 break;
216         }
217     }
218
219     hb_log( "encx264: opening libx264 (pass %d)", job->pass );
220     pv->x264 = x264_encoder_open( &param );
221
222     x264_encoder_headers( pv->x264, &nal, &nal_count );
223
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 );
228
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 );
233
234     x264_picture_alloc( &pv->pic_in, X264_CSP_I420,
235             job->width, job->height );
236
237     pv->dts_write_index = 0;
238     pv->dts_read_index = 0;
239     pv->next_chap = 0;
240
241     return 0;
242 }
243
244 void encx264Close( hb_work_object_t * w )
245 {
246     hb_work_private_t * pv = w->private_data;
247     x264_picture_clean( &pv->pic_in );
248     x264_encoder_close( pv->x264 );
249     free( pv );
250     w->private_data = NULL;
251
252     /* TODO */
253 }
254
255 int encx264Work( hb_work_object_t * w, hb_buffer_t ** buf_in,
256                   hb_buffer_t ** buf_out )
257 {
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;
262     int           i_nal;
263     x264_nal_t  * nal;
264     int i;
265
266     if( in->data )
267     {
268         /* XXX avoid this memcpy ? */
269         memcpy( pv->pic_in.img.plane[0], in->data, job->width * job->height );
270         if( job->grayscale )
271         {
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 );
275         }
276         else
277         {
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 );
282         }
283
284         if( in->new_chap && job->chapter_markers )
285         {
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 )
293             {
294                 pv->next_chap = in->start;
295             }
296             /* don't let 'work_loop' put a chapter mark on the wrong buffer */
297             in->new_chap = 0;
298         }
299         else
300         {
301             pv->pic_in.i_type = X264_TYPE_AUTO;
302         }
303         pv->pic_in.i_qpplus1 = 0;
304
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++;
309
310         /* Feed the input DTS to x264 so it can figure out proper output PTS */
311         pv->pic_in.i_pts = in->start;
312
313         x264_encoder_encode( pv->x264, &nal, &i_nal,
314                              &pv->pic_in, &pic_out );        
315     }
316     else
317     {
318         x264_encoder_encode( pv->x264, &nal, &i_nal,
319                              NULL, &pic_out );
320         /* No more delayed B frames */
321         if( i_nal == 0 )
322         {
323             *buf_out = NULL;
324             return HB_WORK_DONE;
325         }
326         else
327         {
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));
332         }
333     }
334
335     if( i_nal )
336     {
337         /* Should be way too large */
338         buf        = hb_buffer_init( 3 * job->width * job->height / 2 );
339         buf->size  = 0;
340         buf->start = in->start;
341         buf->stop  = in->stop;
342         buf->frametype   = 0;
343
344         int64_t dts_start, dts_stop;
345
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++;
350
351         for( i = 0; i < i_nal; i++ )
352         {
353             int size, data;
354
355             data = buf->alloc - buf->size;
356             if( ( size = x264_nal_encode( buf->data + buf->size, &data,
357                                           1, &nal[i] ) ) < 1 )
358             {
359                 continue;
360             }
361
362             if( job->mux & HB_MUX_AVI )
363             {
364                 if( nal[i].i_ref_idc == NAL_PRIORITY_HIGHEST )
365                 {
366                     buf->frametype = HB_FRAME_KEY;
367                 }
368                 buf->size += size;
369                 continue;
370             }
371
372             /* H.264 in .mp4 */
373             switch( buf->data[buf->size+4] & 0x1f )
374             {
375                 case 0x7:
376                 case 0x8:
377                     /* SPS, PPS */
378                     break;
379
380                 default:
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 )
387                     {
388                     /*  Decide what type of frame we have. */
389                         case X264_TYPE_IDR:
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
394                                chapter start. */
395                             if( pv->next_chap != 0 && pv->next_chap <= pic_out.i_pts )
396                             {
397                                 pv->next_chap = 0;
398                                 buf->new_chap = 1;
399                             }
400                             break;
401                         case X264_TYPE_I:
402                             buf->frametype = HB_FRAME_I;
403                             break;
404                         case X264_TYPE_P:
405                             buf->frametype = HB_FRAME_P;
406                             break;
407                         case X264_TYPE_B:
408                             buf->frametype = HB_FRAME_B;
409                             break;
410                     /*  This is for b-pyramid, which has reference b-frames
411                         However, it doesn't seem to ever be used... */
412                         case X264_TYPE_BREF:
413                             buf->frametype = HB_FRAME_BREF;
414                             break;
415                     /*  If it isn't the above, what type of frame is it?? */
416                         default:
417                             buf->frametype = 0;
418                     }
419
420
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. */
427
428                     buf->renderOffset = pic_out.i_pts - dts_start + 1000000;
429
430                     /* Send out the next dts values */
431                     buf->start = dts_start;
432                     buf->stop  = dts_stop;
433
434                     buf->size += size;
435             }
436         }
437     }
438
439     else
440         buf = NULL;
441
442     *buf_out = buf;
443
444     return HB_WORK_OK;
445 }
446
447