OSDN Git Service

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