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;
47 ti.aspect_numerator = job->pixel_aspect_width;
48 ti.aspect_denominator = job->pixel_aspect_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 || job->vquality > 1.0)
68 ti.target_bitrate = job->vbitrate * 1000;
69 ti.keyframe_data_target_bitrate = job->vbitrate * 1000 * 1.5;
74 ti.target_bitrate = 0;
75 ti.quality = 63 * job->vquality;
78 theora_encode_init( &pv->theora, &ti );
79 theora_info_clear( &ti );
81 theora_encode_header( &pv->theora, &op );
82 memcpy(w->config->theora.headers[0], &op, sizeof(op));
83 memcpy(w->config->theora.headers[0] + sizeof(op), op.packet, op.bytes );
85 theora_comment_init(&tc);
86 theora_encode_comment(&tc,&op);
87 memcpy(w->config->theora.headers[1], &op, sizeof(op));
88 memcpy(w->config->theora.headers[1] + sizeof(op), op.packet, op.bytes );
91 theora_encode_tables(&pv->theora, &op);
92 memcpy(w->config->theora.headers[2], &op, sizeof(op));
93 memcpy(w->config->theora.headers[2] + sizeof(op), op.packet, op.bytes );
98 /***********************************************************************
100 ***********************************************************************
102 **********************************************************************/
103 void enctheoraClose( hb_work_object_t * w )
105 hb_work_private_t * pv = w->private_data;
106 /* TODO: Free alloc'd */
109 w->private_data = NULL;
112 /***********************************************************************
114 ***********************************************************************
116 **********************************************************************/
117 int enctheoraWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
118 hb_buffer_t ** buf_out )
120 hb_work_private_t * pv = w->private_data;
121 hb_job_t * job = pv->job;
122 hb_buffer_t * in = *buf_in, * buf;
128 // EOF on input - send it downstream & say we're done.
129 // XXX may need to flush packets via a call to
130 // theora_encode_packetout(&pv->theora, 1, &op);
131 // but we don't have a timestamp to put on those packets so we
132 // drop them for now.
138 memset(&op, 0, sizeof(op));
139 memset(&yuv, 0, sizeof(yuv));
141 yuv.y_width = job->width;
142 yuv.y_height = job->height;
143 yuv.y_stride = job->width;
145 yuv.uv_width = job->width / 2;
146 yuv.uv_height = job->height / 2;
147 yuv.uv_stride = job->width / 2;
150 yuv.u = in->data + job->width * job->height;
151 yuv.v = in->data + job->width * job->height * 5/4;
153 theora_encode_YUVin(&pv->theora, &yuv);
155 theora_encode_packetout(&pv->theora, 0, &op);
157 buf = hb_buffer_init( op.bytes + sizeof(op) );
158 memcpy(buf->data, &op, sizeof(op));
159 memcpy(buf->data + sizeof(op), op.packet, op.bytes);
160 buf->frametype = ( theora_packet_iskeyframe(&op) ) ? HB_FRAME_KEY : HB_FRAME_REF;
161 buf->start = in->start;
162 buf->stop = in->stop;