Mercurial > libavcodec.hg
comparison libtheoraenc.c @ 10553:86c7e3c6de00 libavcodec
Update libtheora wrapper to use the 1.0 API
author | conrad |
---|---|
date | Sun, 22 Nov 2009 21:08:37 +0000 |
parents | f1ef8d3221c8 |
children | deabe9f7571b |
comparison
equal
deleted
inserted
replaced
10552:e2d17f7f9408 | 10553:86c7e3c6de00 |
---|---|
34 #include "libavutil/intreadwrite.h" | 34 #include "libavutil/intreadwrite.h" |
35 #include "libavutil/log.h" | 35 #include "libavutil/log.h" |
36 #include "avcodec.h" | 36 #include "avcodec.h" |
37 | 37 |
38 /* libtheora includes */ | 38 /* libtheora includes */ |
39 #include <theora/theora.h> | 39 #include <theora/theoraenc.h> |
40 | 40 |
41 typedef struct TheoraContext { | 41 typedef struct TheoraContext { |
42 theora_state t_state; | 42 th_enc_ctx *t_state; |
43 } TheoraContext; | 43 } TheoraContext; |
44 | 44 |
45 /*! | 45 /*! |
46 Concatenates an ogg_packet into the extradata. | 46 Concatenates an ogg_packet into the extradata. |
47 */ | 47 */ |
78 return 0; | 78 return 0; |
79 } | 79 } |
80 | 80 |
81 static av_cold int encode_init(AVCodecContext* avc_context) | 81 static av_cold int encode_init(AVCodecContext* avc_context) |
82 { | 82 { |
83 theora_info t_info; | 83 th_info t_info; |
84 theora_comment t_comment; | 84 th_comment t_comment; |
85 ogg_packet o_packet; | 85 ogg_packet o_packet; |
86 unsigned int offset; | 86 unsigned int offset; |
87 TheoraContext *h = avc_context->priv_data; | 87 TheoraContext *h = avc_context->priv_data; |
88 uint32_t gop_size = avc_context->gop_size; | |
88 | 89 |
89 /* Set up the theora_info struct */ | 90 /* Set up the theora_info struct */ |
90 theora_info_init(&t_info); | 91 th_info_init(&t_info); |
91 t_info.width = FFALIGN(avc_context->width, 16); | 92 t_info.frame_width = FFALIGN(avc_context->width, 16); |
92 t_info.height = FFALIGN(avc_context->height, 16); | 93 t_info.frame_height = FFALIGN(avc_context->height, 16); |
93 t_info.frame_width = avc_context->width; | 94 t_info.pic_width = avc_context->width; |
94 t_info.frame_height = avc_context->height; | 95 t_info.pic_height = avc_context->height; |
95 t_info.offset_x = 0; | 96 t_info.pic_x = 0; |
96 t_info.offset_y = avc_context->height & 0xf; | 97 t_info.pic_y = 0; |
97 /* Swap numerator and denominator as time_base in AVCodecContext gives the | 98 /* Swap numerator and denominator as time_base in AVCodecContext gives the |
98 * time period between frames, but theora_info needs the framerate. */ | 99 * time period between frames, but theora_info needs the framerate. */ |
99 t_info.fps_numerator = avc_context->time_base.den; | 100 t_info.fps_numerator = avc_context->time_base.den; |
100 t_info.fps_denominator = avc_context->time_base.num; | 101 t_info.fps_denominator = avc_context->time_base.num; |
101 if (avc_context->sample_aspect_ratio.num) { | 102 if (avc_context->sample_aspect_ratio.num) { |
103 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; | 104 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; |
104 } else { | 105 } else { |
105 t_info.aspect_numerator = 1; | 106 t_info.aspect_numerator = 1; |
106 t_info.aspect_denominator = 1; | 107 t_info.aspect_denominator = 1; |
107 } | 108 } |
108 t_info.colorspace = OC_CS_UNSPECIFIED; | 109 t_info.colorspace = TH_CS_UNSPECIFIED; |
109 t_info.pixelformat = OC_PF_420; | 110 t_info.pixel_fmt = TH_PF_420; |
110 t_info.keyframe_frequency = avc_context->gop_size; | |
111 t_info.keyframe_frequency_force = avc_context->gop_size; | |
112 t_info.keyframe_mindistance = avc_context->keyint_min; | |
113 | |
114 t_info.quick_p = 1; | |
115 t_info.dropframes_p = 0; | |
116 t_info.keyframe_auto_p = 1; | |
117 t_info.keyframe_data_target_bitrate = t_info.target_bitrate * 1.5; | |
118 t_info.keyframe_auto_threshold = 80; | |
119 t_info.noise_sensitivity = 1; | |
120 t_info.sharpness = 0; | |
121 | 111 |
122 if (avc_context->flags & CODEC_FLAG_QSCALE) { | 112 if (avc_context->flags & CODEC_FLAG_QSCALE) { |
123 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 | 113 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 |
124 Theora accepts a quality parameter p, which is: | 114 Theora accepts a quality parameter p, which is: |
125 * 0 <= p <=63 | 115 * 0 <= p <=63 |
131 t_info.target_bitrate = avc_context->bit_rate; | 121 t_info.target_bitrate = avc_context->bit_rate; |
132 t_info.quality = 0; | 122 t_info.quality = 0; |
133 } | 123 } |
134 | 124 |
135 /* Now initialise libtheora */ | 125 /* Now initialise libtheora */ |
136 if (theora_encode_init(&(h->t_state), &t_info)) { | 126 h->t_state = th_encode_alloc(&t_info); |
127 if (!h->t_state) { | |
137 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); | 128 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); |
138 return -1; | 129 return -1; |
139 } | 130 } |
140 | 131 |
141 /* Clear up theora_info struct */ | 132 /* Clear up theora_info struct */ |
142 theora_info_clear(&t_info); | 133 th_info_clear(&t_info); |
134 | |
135 if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, | |
136 &gop_size, sizeof(gop_size))) { | |
137 av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n"); | |
138 return -1; | |
139 } | |
143 | 140 |
144 /* | 141 /* |
145 Output first header packet consisting of theora | 142 Output first header packet consisting of theora |
146 header, comment, and tables. | 143 header, comment, and tables. |
147 | 144 |
148 Each one is prefixed with a 16bit size, then they | 145 Each one is prefixed with a 16bit size, then they |
149 are concatenated together into ffmpeg's extradata. | 146 are concatenated together into ffmpeg's extradata. |
150 */ | 147 */ |
151 offset = 0; | 148 offset = 0; |
152 | 149 |
153 /* Header */ | 150 /* Headers */ |
154 theora_encode_header(&(h->t_state), &o_packet); | 151 th_comment_init(&t_comment); |
155 if (concatenate_packet(&offset, avc_context, &o_packet)) | 152 |
156 return -1; | 153 while (th_encode_flushheader(h->t_state, &t_comment, &o_packet)) |
157 | 154 if (concatenate_packet(&offset, avc_context, &o_packet)) |
158 /* Comment */ | 155 return -1; |
159 theora_comment_init(&t_comment); | 156 |
160 theora_encode_comment(&t_comment, &o_packet); | 157 th_comment_clear(&t_comment); |
161 if (concatenate_packet(&offset, avc_context, &o_packet)) | |
162 return -1; | |
163 /* Clear up theora_comment struct before we reset the packet */ | |
164 theora_comment_clear(&t_comment); | |
165 /* And despite documentation to the contrary, theora_comment_clear | |
166 * does not release the packet */ | |
167 ogg_packet_clear(&o_packet); | |
168 | |
169 /* Tables */ | |
170 theora_encode_tables(&(h->t_state), &o_packet); | |
171 if (concatenate_packet(&offset, avc_context, &o_packet)) | |
172 return -1; | |
173 | 158 |
174 /* Set up the output AVFrame */ | 159 /* Set up the output AVFrame */ |
175 avc_context->coded_frame= avcodec_alloc_frame(); | 160 avc_context->coded_frame= avcodec_alloc_frame(); |
176 | 161 |
177 return 0; | 162 return 0; |
178 } | 163 } |
179 | 164 |
180 static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf, | 165 static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf, |
181 int buf_size, void *data) | 166 int buf_size, void *data) |
182 { | 167 { |
183 yuv_buffer t_yuv_buffer; | 168 th_ycbcr_buffer t_yuv_buffer; |
184 TheoraContext *h = avc_context->priv_data; | 169 TheoraContext *h = avc_context->priv_data; |
185 AVFrame *frame = data; | 170 AVFrame *frame = data; |
186 ogg_packet o_packet; | 171 ogg_packet o_packet; |
187 int result; | 172 int result, i; |
188 | 173 |
189 assert(avc_context->pix_fmt == PIX_FMT_YUV420P); | 174 assert(avc_context->pix_fmt == PIX_FMT_YUV420P); |
190 | 175 |
191 /* Copy planes to the theora yuv_buffer */ | 176 /* Copy planes to the theora yuv_buffer */ |
192 if (frame->linesize[1] != frame->linesize[2]) { | 177 for (i = 0; i < 3; i++) { |
193 av_log(avc_context, AV_LOG_ERROR, "U and V stride differ\n"); | 178 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> !!i; |
194 return -1; | 179 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> !!i; |
195 } | 180 t_yuv_buffer[i].stride = frame->linesize[i]; |
196 | 181 t_yuv_buffer[i].data = frame->data[i]; |
197 t_yuv_buffer.y_width = FFALIGN(avc_context->width, 16); | 182 } |
198 t_yuv_buffer.y_height = FFALIGN(avc_context->height, 16); | |
199 t_yuv_buffer.y_stride = frame->linesize[0]; | |
200 t_yuv_buffer.uv_width = t_yuv_buffer.y_width / 2; | |
201 t_yuv_buffer.uv_height = t_yuv_buffer.y_height / 2; | |
202 t_yuv_buffer.uv_stride = frame->linesize[1]; | |
203 | |
204 t_yuv_buffer.y = frame->data[0]; | |
205 t_yuv_buffer.u = frame->data[1]; | |
206 t_yuv_buffer.v = frame->data[2]; | |
207 | 183 |
208 /* Now call into theora_encode_YUVin */ | 184 /* Now call into theora_encode_YUVin */ |
209 result = theora_encode_YUVin(&(h->t_state), &t_yuv_buffer); | 185 result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer); |
210 if (result) { | 186 if (result) { |
211 const char* message; | 187 const char* message; |
212 switch (result) { | 188 switch (result) { |
213 case -1: | 189 case -1: |
214 message = "differing frame sizes"; | 190 message = "differing frame sizes"; |
215 break; | 191 break; |
216 case OC_EINVAL: | 192 case TH_EINVAL: |
217 message = "encoder is not ready or is finished"; | 193 message = "encoder is not ready or is finished"; |
218 break; | 194 break; |
219 default: | 195 default: |
220 message = "unknown reason"; | 196 message = "unknown reason"; |
221 break; | 197 break; |
223 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result); | 199 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result); |
224 return -1; | 200 return -1; |
225 } | 201 } |
226 | 202 |
227 /* Pick up returned ogg_packet */ | 203 /* Pick up returned ogg_packet */ |
228 result = theora_encode_packetout(&(h->t_state), 0, &o_packet); | 204 result = th_encode_packetout(h->t_state, 0, &o_packet); |
229 switch (result) { | 205 switch (result) { |
230 case 0: | 206 case 0: |
231 /* No packet is ready */ | 207 /* No packet is ready */ |
232 return 0; | 208 return 0; |
233 case 1: | 209 case 1: |
256 ogg_packet o_packet; | 232 ogg_packet o_packet; |
257 TheoraContext *h = avc_context->priv_data; | 233 TheoraContext *h = avc_context->priv_data; |
258 int result; | 234 int result; |
259 const char* message; | 235 const char* message; |
260 | 236 |
261 result = theora_encode_packetout(&(h->t_state), 1, &o_packet); | 237 result = th_encode_packetout(h->t_state, 1, &o_packet); |
262 theora_clear(&(h->t_state)); | 238 th_encode_free(h->t_state); |
263 av_freep(&avc_context->coded_frame); | 239 av_freep(&avc_context->coded_frame); |
264 av_freep(&avc_context->extradata); | 240 av_freep(&avc_context->extradata); |
265 avc_context->extradata_size = 0; | 241 avc_context->extradata_size = 0; |
266 | 242 |
267 switch (result) { | 243 switch (result) { |