OSDN Git Service

LinGui: remove target file size option
[handbrake-jp/handbrake-jp-git.git] / libhb / enctheora.c
1 /* This file is part of the HandBrake source code.
2    Homepage: <http://handbrake.fr/>.
3    It may be used under the terms of the GNU General Public License. */
4
5 #include "hb.h"
6 #include "theora/codec.h"
7 #include "theora/theoraenc.h"
8
9 int  enctheoraInit( hb_work_object_t *, hb_job_t * );
10 int  enctheoraWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
11 void enctheoraClose( hb_work_object_t * );
12
13 hb_work_object_t hb_enctheora =
14 {
15     WORK_ENCTHEORA,
16     "Theora encoder (libtheora)",
17     enctheoraInit,
18     enctheoraWork,
19     enctheoraClose
20 };
21
22 struct hb_work_private_s
23 {
24     hb_job_t    * job;
25
26     th_enc_ctx    * ctx;
27
28     FILE          * file;
29     unsigned char   stat_buf[80];
30     int             stat_read;
31     int             stat_fill;
32 };
33
34 int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
35 {
36     int keyframe_frequency, log_keyframe, ret;
37     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
38     w->private_data = pv;
39
40     pv->job = job;
41
42     if( job->pass != 0 && job->pass != -1 )
43     {
44         char filename[1024];
45         memset( filename, 0, 1024 );
46         hb_get_tempory_filename( job->h, filename, "theroa.log" );
47         if ( job->pass == 1 )
48         {
49             pv->file = fopen( filename, "wb" );
50         }
51         else
52         {
53             pv->file = fopen( filename, "rb" );
54         }
55     }
56
57     th_info ti;
58     th_comment tc;
59     ogg_packet op;
60     th_info_init( &ti );
61
62     /* Frame width and height need to be multiples of 16 */
63     ti.pic_width = job->width;
64     ti.pic_height = job->height;
65     ti.frame_width = (job->width + 0xf) & ~0xf;
66     ti.frame_height = (job->height + 0xf) & ~0xf;
67     ti.pic_x = ti.pic_y = 0;
68
69     ti.fps_numerator = job->vrate;
70     ti.fps_denominator = job->vrate_base;
71     if( job->anamorphic.mode )
72     {
73         ti.aspect_numerator = job->anamorphic.par_width;
74         ti.aspect_denominator = job->anamorphic.par_height;
75     }
76     else
77     {
78         ti.aspect_numerator = ti.aspect_denominator = 1;
79     }
80     ti.colorspace = TH_CS_UNSPECIFIED;
81     ti.pixel_fmt = TH_PF_420;
82     if (job->vquality < 0.0)
83     {
84         ti.target_bitrate = job->vbitrate * 1000;
85         ti.quality = 0;
86     }
87     else
88     {
89         ti.target_bitrate = 0;
90         
91         if( job->vquality > 0 && job->vquality < 1 )
92         {
93             ti.quality = 63 * job->vquality;            
94         }
95         else
96         {
97             ti.quality = job->vquality;
98         }
99     }
100
101     if ( job->pass == 2 && !job->cfr )
102     {
103         /* Even though the framerate might be different due to VFR,
104            we still want the same keyframe intervals as the 1st pass,
105            so the 1st pass stats won't conflict on frame decisions.    */
106         hb_interjob_t * interjob = hb_interjob_get( job->h );
107         keyframe_frequency = ( 10 * interjob->vrate / interjob->vrate_base ) + 1;
108     }
109     else
110     {
111         int fps = job->vrate / job->vrate_base;
112
113         /* adjust +1 when fps has remainder to bump
114            { 23.976, 29.976, 59.94 } to { 24, 30, 60 } */
115         if (job->vrate % job->vrate_base)
116             fps += 1;
117
118         keyframe_frequency = fps * 10;
119     }
120     int tmp = keyframe_frequency - 1;
121     for (log_keyframe = 0; tmp; log_keyframe++)
122         tmp >>= 1;
123         
124     hb_log("theora: keyint: %i", keyframe_frequency);
125
126     ti.keyframe_granule_shift = log_keyframe;
127
128     pv->ctx = th_encode_alloc( &ti );
129     th_info_clear( &ti );
130
131     ret = th_encode_ctl(pv->ctx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
132                         &keyframe_frequency, sizeof(keyframe_frequency));
133     if( ret < 0 )
134     {
135         hb_log("theora: Could not set keyframe interval to %d", keyframe_frequency);
136     }
137
138     /* Set "soft target" rate control which improves quality at the
139      * expense of solid bitrate caps */
140     int arg = TH_RATECTL_CAP_UNDERFLOW;
141     ret = th_encode_ctl(pv->ctx, TH_ENCCTL_SET_RATE_FLAGS, &arg, sizeof(arg));
142     if( ret < 0 )
143     {
144         hb_log("theora: Could not set soft ratecontrol");
145     }
146     if( job->pass != 0 && job->pass != -1 )
147     {
148         arg = keyframe_frequency * 7 >> 1;
149         ret = th_encode_ctl(pv->ctx, TH_ENCCTL_SET_RATE_BUFFER, &arg, sizeof(arg));
150         if( ret < 0 )
151         {
152             hb_log("theora: Could not set rate control buffer");
153         }
154     }
155
156     if( job->pass == 1 )
157     {
158         unsigned char *buffer;
159         int bytes;
160         bytes = th_encode_ctl(pv->ctx, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
161         if( bytes < 0 )
162         {
163             hb_error("Could not set up the first pass of two-pass mode.\n");
164             hb_error("Did you remember to specify an estimated bitrate?\n");
165             return 1;
166         }
167         if( fwrite( buffer, 1, bytes, pv->file ) < bytes )
168         {
169             hb_error("Unable to write to two-pass data file.\n");
170             return 1;
171         }
172         fflush( pv->file );
173     }
174     if( job->pass == 2 )
175     {
176         /* Enable the second pass here.
177          * We make this call just to set the encoder into 2-pass mode, because
178          * by default enabling two-pass sets the buffer delay to the whole file
179          * (because there's no way to explicitly request that behavior).
180          * If we waited until we were actually encoding, it would overwite our
181          * settings.*/
182         hb_log("enctheora: init 2nd pass");
183         if( th_encode_ctl( pv->ctx, TH_ENCCTL_2PASS_IN, NULL, 0) < 0)
184         {
185             hb_log("theora: Could not set up the second pass of two-pass mode.");
186             return 1;
187         }
188     }
189
190     th_comment_init( &tc );
191
192     th_encode_flushheader( pv->ctx, &tc, &op );
193     memcpy(w->config->theora.headers[0], &op, sizeof(op));
194     memcpy(w->config->theora.headers[0] + sizeof(op), op.packet, op.bytes );
195
196     th_encode_flushheader( pv->ctx, &tc, &op );
197     memcpy(w->config->theora.headers[1], &op, sizeof(op));
198     memcpy(w->config->theora.headers[1] + sizeof(op), op.packet, op.bytes );
199
200     th_encode_flushheader( pv->ctx, &tc, &op );
201     memcpy(w->config->theora.headers[2], &op, sizeof(op));
202     memcpy(w->config->theora.headers[2] + sizeof(op), op.packet, op.bytes );
203
204     th_comment_clear( &tc );
205
206     return 0;
207 }
208
209 /***********************************************************************
210  * Close
211  ***********************************************************************
212  *
213  **********************************************************************/
214 void enctheoraClose( hb_work_object_t * w )
215 {
216     hb_work_private_t * pv = w->private_data;
217
218     th_encode_free( pv->ctx );
219
220     if( pv->file )
221     {
222         fclose( pv->file );
223     }
224     free( pv );
225     w->private_data = NULL;
226 }
227
228 /***********************************************************************
229  * Work
230  ***********************************************************************
231  *
232  **********************************************************************/
233 int enctheoraWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
234                  hb_buffer_t ** buf_out )
235 {
236     hb_work_private_t * pv = w->private_data;
237     hb_job_t * job = pv->job;
238     hb_buffer_t * in = *buf_in, * buf;
239     th_ycbcr_buffer ycbcr;
240     ogg_packet op;
241
242     int frame_width, frame_height;
243
244     if ( in->size <= 0 )
245     {
246         // EOF on input - send it downstream & say we're done.
247         // XXX may need to flush packets via a call to
248         //  th_encode_packetout( pv->ctx, 1, &op );
249         // but we don't have a timestamp to put on those packets so we
250         // drop them for now.
251         *buf_out = in;
252         *buf_in = NULL;
253         th_encode_packetout( pv->ctx, 1, &op );
254         if( job->pass == 1 )
255         {
256             unsigned char *buffer;
257             int bytes;
258
259             bytes = th_encode_ctl(pv->ctx, TH_ENCCTL_2PASS_OUT, 
260                                   &buffer, sizeof(buffer));
261             if( bytes < 0 )
262             {
263                 fprintf(stderr,"Could not read two-pass data from encoder.\n");
264                 return HB_WORK_DONE;
265             }
266             fseek( pv->file, 0, SEEK_SET );
267             if( fwrite( buffer, 1, bytes, pv->file ) < bytes)
268             {
269                 fprintf(stderr,"Unable to write to two-pass data file.\n");
270                 return HB_WORK_DONE;
271             }
272             fflush( pv->file );
273         }
274         return HB_WORK_DONE;
275     }
276
277     if( job->pass == 2 )
278     {
279         for(;;)
280         {
281             int bytes, size, ret;
282             /*Ask the encoder how many bytes it would like.*/
283             bytes = th_encode_ctl( pv->ctx, TH_ENCCTL_2PASS_IN, NULL, 0 );
284             if( bytes < 0 )
285             {
286                 hb_error("Error requesting stats size in second pass.");
287                 *job->die = 1;
288                 return HB_WORK_DONE;
289             }
290
291             /*If it's got enough, stop.*/
292             if( bytes == 0 ) break;
293
294             /*Read in some more bytes, if necessary.*/
295             if( bytes > pv->stat_fill - pv->stat_read )
296                 size = bytes - (pv->stat_fill - pv->stat_read);
297             else
298                 size = 0;
299             if( size > 80 - pv->stat_fill )
300                 size = 80 - pv->stat_fill;
301             if( size > 0 &&
302                 fread( pv->stat_buf+pv->stat_fill, 1, size, pv->file ) < size )
303             {
304                 hb_error("Could not read frame data from two-pass data file!");
305                 *job->die = 1;
306                 return HB_WORK_DONE;
307             }
308             pv->stat_fill += size;
309
310             /*And pass them off.*/
311             if( bytes > pv->stat_fill - pv->stat_read )
312                 bytes = pv->stat_fill - pv->stat_read;
313             ret = th_encode_ctl( pv->ctx, TH_ENCCTL_2PASS_IN, 
314                                  pv->stat_buf+pv->stat_read, bytes);
315             if( ret < 0 )
316             {
317                 hb_error("Error submitting pass data in second pass.");
318                 *job->die = 1;
319                 return HB_WORK_DONE;
320             }
321             /*If the encoder consumed the whole buffer, reset it.*/
322             if( ret >= pv->stat_fill - pv->stat_read )
323                 pv->stat_read = pv->stat_fill = 0;
324             /*Otherwise remember how much it used.*/
325             else 
326                 pv->stat_read += ret;
327         }
328     }
329     memset(&op, 0, sizeof(op));
330     memset(&ycbcr, 0, sizeof(ycbcr));
331
332     frame_width = (job->width + 0xf) & ~0xf;
333     frame_height = (job->height + 0xf) & ~0xf;
334
335     // Y
336     ycbcr[0].width = frame_width;
337     ycbcr[0].height = frame_height;
338     ycbcr[0].stride = job->width;
339
340     // CbCr decimated by factor of 2 in both width and height
341     ycbcr[1].width  = ycbcr[2].width  = (frame_width + 1) / 2;
342     ycbcr[1].height = ycbcr[2].height = (frame_height + 1) / 2;
343     ycbcr[1].stride = ycbcr[2].stride = (job->width + 1) / 2;
344
345     ycbcr[0].data = in->data;
346     ycbcr[1].data = ycbcr[0].data + (ycbcr[0].stride * job->height);
347     ycbcr[2].data = ycbcr[1].data + (ycbcr[1].stride * ((job->height+1)/2));
348
349     th_encode_ycbcr_in( pv->ctx, ycbcr );
350
351     if( job->pass == 1 )
352     {
353         unsigned char *buffer;
354         int bytes;
355
356         bytes = th_encode_ctl(pv->ctx, TH_ENCCTL_2PASS_OUT, 
357                               &buffer, sizeof(buffer));
358         if( bytes < 0 )
359         {
360             fprintf(stderr,"Could not read two-pass data from encoder.\n");
361             *job->die = 1;
362             return HB_WORK_DONE;
363         }
364         if( fwrite( buffer, 1, bytes, pv->file ) < bytes)
365         {
366             fprintf(stderr,"Unable to write to two-pass data file.\n");
367             *job->die = 1;
368             return HB_WORK_DONE;
369         }
370         fflush( pv->file );
371     }
372     th_encode_packetout( pv->ctx, 0, &op );
373
374     buf = hb_buffer_init( op.bytes + sizeof(op) );
375     memcpy(buf->data, &op, sizeof(op));
376     memcpy(buf->data + sizeof(op), op.packet, op.bytes);
377     buf->frametype = ( th_packet_iskeyframe(&op) ) ? HB_FRAME_KEY : HB_FRAME_REF;
378     buf->start = in->start;
379     buf->stop  = in->stop;
380
381     *buf_out = buf;
382
383     return HB_WORK_OK;
384 }
385