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/theora.h"
8 int enctheoraInit( hb_work_object_t *, hb_job_t * );
9 int enctheoraWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
10 void enctheoraClose( hb_work_object_t * );
12 hb_work_object_t hb_enctheora =
15 "Theora encoder (libtheora)",
21 struct hb_work_private_s
28 int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
30 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
38 theora_info_init( &ti );
40 ti.width = ti.frame_width = job->width;
41 ti.height = ti.frame_height = job->height;
42 ti.offset_x = ti.offset_y = 0;
43 ti.fps_numerator = job->vrate;
44 ti.fps_denominator = job->vrate_base;
45 if( job->anamorphic.mode )
47 ti.aspect_numerator = job->anamorphic.par_width;
48 ti.aspect_denominator = job->anamorphic.par_height;
52 ti.aspect_numerator = ti.aspect_denominator = 1;
54 ti.colorspace = OC_CS_UNSPECIFIED;
55 ti.pixelformat = OC_PF_420;
56 ti.keyframe_auto_p = 1;
57 ti.keyframe_frequency = (job->vrate / job->vrate_base) + 1;
58 ti.keyframe_frequency_force = (10 * job->vrate / job->vrate_base) + 1;
59 /* From encoder_example.c */
62 ti.keyframe_auto_threshold = 80;
63 ti.keyframe_mindistance = 8;
64 ti.noise_sensitivity = 1;
66 if (job->vquality < 0.0)
68 ti.target_bitrate = job->vbitrate * 1000;
69 ti.keyframe_data_target_bitrate = job->vbitrate * 1000 * 1.5;
74 ti.target_bitrate = 0;
76 if( job->vquality > 0 && job->vquality < 1 )
78 ti.quality = 63 * job->vquality;
82 ti.quality = job->vquality;
86 theora_encode_init( &pv->theora, &ti );
87 theora_info_clear( &ti );
89 theora_encode_header( &pv->theora, &op );
90 memcpy(w->config->theora.headers[0], &op, sizeof(op));
91 memcpy(w->config->theora.headers[0] + sizeof(op), op.packet, op.bytes );
93 theora_comment_init(&tc);
94 theora_encode_comment(&tc,&op);
95 memcpy(w->config->theora.headers[1], &op, sizeof(op));
96 memcpy(w->config->theora.headers[1] + sizeof(op), op.packet, op.bytes );
99 theora_encode_tables(&pv->theora, &op);
100 memcpy(w->config->theora.headers[2], &op, sizeof(op));
101 memcpy(w->config->theora.headers[2] + sizeof(op), op.packet, op.bytes );
106 /***********************************************************************
108 ***********************************************************************
110 **********************************************************************/
111 void enctheoraClose( hb_work_object_t * w )
113 hb_work_private_t * pv = w->private_data;
114 /* TODO: Free alloc'd */
117 w->private_data = NULL;
120 /***********************************************************************
122 ***********************************************************************
124 **********************************************************************/
125 int enctheoraWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
126 hb_buffer_t ** buf_out )
128 hb_work_private_t * pv = w->private_data;
129 hb_job_t * job = pv->job;
130 hb_buffer_t * in = *buf_in, * buf;
136 // EOF on input - send it downstream & say we're done.
137 // XXX may need to flush packets via a call to
138 // theora_encode_packetout(&pv->theora, 1, &op);
139 // but we don't have a timestamp to put on those packets so we
140 // drop them for now.
146 memset(&op, 0, sizeof(op));
147 memset(&yuv, 0, sizeof(yuv));
149 yuv.y_width = job->width;
150 yuv.y_height = job->height;
151 yuv.y_stride = job->width;
153 yuv.uv_width = (job->width + 1) / 2;
154 yuv.uv_height = (job->height + 1) / 2;
155 yuv.uv_stride = yuv.uv_width;
158 yuv.u = in->data + job->width * job->height;
159 yuv.v = in->data + ( job->width * job->height ) + ( yuv.uv_width * yuv.uv_height );
161 theora_encode_YUVin(&pv->theora, &yuv);
163 theora_encode_packetout(&pv->theora, 0, &op);
165 buf = hb_buffer_init( op.bytes + sizeof(op) );
166 memcpy(buf->data, &op, sizeof(op));
167 memcpy(buf->data + sizeof(op), op.packet, op.bytes);
168 buf->frametype = ( theora_packet_iskeyframe(&op) ) ? HB_FRAME_KEY : HB_FRAME_REF;
169 buf->start = in->start;
170 buf->stop = in->stop;