OSDN Git Service

import 0.9.3
[handbrake-jp/handbrake-jp.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/theora.h"
7
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 * );
11
12 hb_work_object_t hb_enctheora =
13 {
14     WORK_ENCTHEORA,
15     "Theora encoder (libtheora)",
16     enctheoraInit,
17     enctheoraWork,
18     enctheoraClose
19 };
20
21 struct hb_work_private_s
22 {
23     hb_job_t * job;
24
25     theora_state theora;
26 };
27
28 int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
29 {
30     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
31     w->private_data = pv;
32
33     pv->job = job;
34
35     theora_info ti;
36     theora_comment tc;
37     ogg_packet op;
38     theora_info_init( &ti );
39
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->pixel_ratio)
46     {
47         ti.aspect_numerator = job->pixel_aspect_width;
48         ti.aspect_denominator = job->pixel_aspect_height;
49     }
50     else
51     {
52         ti.aspect_numerator = ti.aspect_denominator = 1;
53     }
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 */
60     ti.quick_p = 1;
61     ti.dropframes_p = 0;
62     ti.keyframe_auto_threshold = 80;
63     ti.keyframe_mindistance = 8;
64     ti.noise_sensitivity = 1;
65     ti.sharpness = 0;
66     if (job->vquality < 0.0 || job->vquality > 1.0)
67     {
68         ti.target_bitrate = job->vbitrate * 1000;
69         ti.keyframe_data_target_bitrate = job->vbitrate * 1000 * 1.5;
70         ti.quality = 0;
71     }
72     else
73     {
74         ti.target_bitrate = 0;
75         ti.quality = 63 * job->vquality;
76     }
77
78     theora_encode_init( &pv->theora, &ti );
79     theora_info_clear( &ti );
80
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 );
84
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 );
89     free(op.packet);
90
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 );
94
95     return 0;
96 }
97
98 /***********************************************************************
99  * Close
100  ***********************************************************************
101  *
102  **********************************************************************/
103 void enctheoraClose( hb_work_object_t * w )
104 {
105     hb_work_private_t * pv = w->private_data;
106     /* TODO: Free alloc'd */
107
108     free( pv );
109     w->private_data = NULL;
110 }
111
112 /***********************************************************************
113  * Work
114  ***********************************************************************
115  *
116  **********************************************************************/
117 int enctheoraWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
118                  hb_buffer_t ** buf_out )
119 {
120     hb_work_private_t * pv = w->private_data;
121     hb_job_t * job = pv->job;
122     hb_buffer_t * in = *buf_in, * buf;
123     yuv_buffer yuv;
124     ogg_packet op;
125
126     if ( in->size <= 0 )
127     {
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.
133         *buf_out = in;
134         *buf_in = NULL;
135        return HB_WORK_DONE;
136     }
137
138     memset(&op, 0, sizeof(op));
139     memset(&yuv, 0, sizeof(yuv));
140
141     yuv.y_width = job->width;
142     yuv.y_height = job->height;
143     yuv.y_stride = job->width;
144
145     yuv.uv_width = (job->width + 1) / 2;
146     yuv.uv_height = (job->height + 1) / 2;
147     yuv.uv_stride = yuv.uv_width;
148
149     yuv.y = in->data;
150     yuv.u = in->data + job->width * job->height;
151     yuv.v = in->data + ( job->width * job->height ) + ( yuv.uv_width * yuv.uv_height );
152
153     theora_encode_YUVin(&pv->theora, &yuv);
154
155     theora_encode_packetout(&pv->theora, 0, &op);
156
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;
163
164     *buf_out = buf;
165
166     return HB_WORK_OK;
167 }
168