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. */
6 #include "theora/codec.h"
7 #include "theora/theoraenc.h"
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 * );
13 hb_work_object_t hb_enctheora =
16 "Theora encoder (libtheora)",
22 struct hb_work_private_s
29 unsigned char stat_buf[80];
34 int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
36 int keyframe_frequency, log_keyframe, ret;
37 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
42 if( job->pass != 0 && job->pass != -1 )
45 memset( filename, 0, 1024 );
46 hb_get_tempory_filename( job->h, filename, "theroa.log" );
49 pv->file = fopen( filename, "wb" );
53 pv->file = fopen( filename, "rb" );
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;
69 ti.fps_numerator = job->vrate;
70 ti.fps_denominator = job->vrate_base;
71 if( job->anamorphic.mode )
73 ti.aspect_numerator = job->anamorphic.par_width;
74 ti.aspect_denominator = job->anamorphic.par_height;
78 ti.aspect_numerator = ti.aspect_denominator = 1;
80 ti.colorspace = TH_CS_UNSPECIFIED;
81 ti.pixel_fmt = TH_PF_420;
82 if (job->vquality < 0.0)
84 ti.target_bitrate = job->vbitrate * 1000;
89 ti.target_bitrate = 0;
91 if( job->vquality > 0 && job->vquality < 1 )
93 ti.quality = 63 * job->vquality;
97 ti.quality = job->vquality;
101 if ( job->pass == 2 && !job->cfr )
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;
111 int fps = job->vrate / job->vrate_base;
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)
118 keyframe_frequency = fps * 10;
120 int tmp = keyframe_frequency - 1;
121 for (log_keyframe = 0; tmp; log_keyframe++)
124 hb_log("theora: keyint: %i", keyframe_frequency);
126 ti.keyframe_granule_shift = log_keyframe;
128 pv->ctx = th_encode_alloc( &ti );
129 th_info_clear( &ti );
131 ret = th_encode_ctl(pv->ctx, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
132 &keyframe_frequency, sizeof(keyframe_frequency));
135 hb_log("theora: Could not set keyframe interval to %d", keyframe_frequency);
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));
144 hb_log("theora: Could not set soft ratecontrol");
146 if( job->pass != 0 && job->pass != -1 )
148 arg = keyframe_frequency * 7 >> 1;
149 ret = th_encode_ctl(pv->ctx, TH_ENCCTL_SET_RATE_BUFFER, &arg, sizeof(arg));
152 hb_log("theora: Could not set rate control buffer");
158 unsigned char *buffer;
160 bytes = th_encode_ctl(pv->ctx, TH_ENCCTL_2PASS_OUT, &buffer, sizeof(buffer));
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");
167 if( fwrite( buffer, 1, bytes, pv->file ) < bytes )
169 hb_error("Unable to write to two-pass data file.\n");
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
182 hb_log("enctheora: init 2nd pass");
183 if( th_encode_ctl( pv->ctx, TH_ENCCTL_2PASS_IN, NULL, 0) < 0)
185 hb_log("theora: Could not set up the second pass of two-pass mode.");
190 th_comment_init( &tc );
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 );
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 );
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 );
204 th_comment_clear( &tc );
209 /***********************************************************************
211 ***********************************************************************
213 **********************************************************************/
214 void enctheoraClose( hb_work_object_t * w )
216 hb_work_private_t * pv = w->private_data;
218 th_encode_free( pv->ctx );
225 w->private_data = NULL;
228 /***********************************************************************
230 ***********************************************************************
232 **********************************************************************/
233 int enctheoraWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
234 hb_buffer_t ** buf_out )
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;
242 int frame_width, frame_height;
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.
253 th_encode_packetout( pv->ctx, 1, &op );
256 unsigned char *buffer;
259 bytes = th_encode_ctl(pv->ctx, TH_ENCCTL_2PASS_OUT,
260 &buffer, sizeof(buffer));
263 fprintf(stderr,"Could not read two-pass data from encoder.\n");
266 fseek( pv->file, 0, SEEK_SET );
267 if( fwrite( buffer, 1, bytes, pv->file ) < bytes)
269 fprintf(stderr,"Unable to write to two-pass data file.\n");
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 );
286 hb_error("Error requesting stats size in second pass.");
291 /*If it's got enough, stop.*/
292 if( bytes == 0 ) break;
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);
299 if( size > 80 - pv->stat_fill )
300 size = 80 - pv->stat_fill;
302 fread( pv->stat_buf+pv->stat_fill, 1, size, pv->file ) < size )
304 hb_error("Could not read frame data from two-pass data file!");
308 pv->stat_fill += size;
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);
317 hb_error("Error submitting pass data in second pass.");
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.*/
326 pv->stat_read += ret;
329 memset(&op, 0, sizeof(op));
330 memset(&ycbcr, 0, sizeof(ycbcr));
332 frame_width = (job->width + 0xf) & ~0xf;
333 frame_height = (job->height + 0xf) & ~0xf;
336 ycbcr[0].width = frame_width;
337 ycbcr[0].height = frame_height;
338 ycbcr[0].stride = job->width;
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;
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));
349 th_encode_ycbcr_in( pv->ctx, ycbcr );
353 unsigned char *buffer;
356 bytes = th_encode_ctl(pv->ctx, TH_ENCCTL_2PASS_OUT,
357 &buffer, sizeof(buffer));
360 fprintf(stderr,"Could not read two-pass data from encoder.\n");
364 if( fwrite( buffer, 1, bytes, pv->file ) < bytes)
366 fprintf(stderr,"Unable to write to two-pass data file.\n");
372 th_encode_packetout( pv->ctx, 0, &op );
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;