Mercurial > libavcodec.hg
comparison libtheoraenc.c @ 10439:b4b55a3d65c9 libavcodec
whitespace cosmetics: prettyprinting, K&R style
author | diego |
---|---|
date | Mon, 19 Oct 2009 15:51:34 +0000 |
parents | 00bd0c4c1489 |
children | f1ef8d3221c8 |
comparison
equal
deleted
inserted
replaced
10438:710e226783f0 | 10439:b4b55a3d65c9 |
---|---|
36 #include "avcodec.h" | 36 #include "avcodec.h" |
37 | 37 |
38 /* libtheora includes */ | 38 /* libtheora includes */ |
39 #include <theora/theora.h> | 39 #include <theora/theora.h> |
40 | 40 |
41 typedef struct TheoraContext{ | 41 typedef struct TheoraContext { |
42 theora_state t_state; | 42 theora_state 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 */ |
48 static int concatenate_packet(unsigned int* offset, AVCodecContext* avc_context, const ogg_packet* packet) | 48 static int concatenate_packet(unsigned int* offset, |
49 AVCodecContext* avc_context, | |
50 const ogg_packet* packet) | |
49 { | 51 { |
50 const char* message = NULL; | 52 const char* message = NULL; |
51 uint8_t* newdata = NULL; | 53 uint8_t* newdata = NULL; |
52 int newsize = avc_context->extradata_size + 2 + packet->bytes; | 54 int newsize = avc_context->extradata_size + 2 + packet->bytes; |
53 | 55 |
54 if (packet->bytes < 0) { | 56 if (packet->bytes < 0) { |
55 message = "ogg_packet has negative size"; | 57 message = "ogg_packet has negative size"; |
56 } else if (packet->bytes > 0xffff) { | 58 } else if (packet->bytes > 0xffff) { |
65 if (message != NULL) { | 67 if (message != NULL) { |
66 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message); | 68 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message); |
67 return -1; | 69 return -1; |
68 } | 70 } |
69 | 71 |
70 avc_context->extradata = newdata; | 72 avc_context->extradata = newdata; |
71 avc_context->extradata_size = newsize; | 73 avc_context->extradata_size = newsize; |
72 AV_WB16(avc_context->extradata + (*offset), packet->bytes); | 74 AV_WB16(avc_context->extradata + (*offset), packet->bytes); |
73 *offset += 2; | 75 *offset += 2; |
74 memcpy( avc_context->extradata + (*offset), packet->packet, packet->bytes ); | 76 memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes); |
75 (*offset) += packet->bytes; | 77 (*offset) += packet->bytes; |
76 return 0; | 78 return 0; |
77 } | 79 } |
78 | 80 |
79 static av_cold int encode_init(AVCodecContext* avc_context) | 81 static av_cold int encode_init(AVCodecContext* avc_context) |
83 ogg_packet o_packet; | 85 ogg_packet o_packet; |
84 unsigned int offset; | 86 unsigned int offset; |
85 TheoraContext *h = avc_context->priv_data; | 87 TheoraContext *h = avc_context->priv_data; |
86 | 88 |
87 /* Set up the theora_info struct */ | 89 /* Set up the theora_info struct */ |
88 theora_info_init( &t_info ); | 90 theora_info_init(&t_info); |
89 t_info.width = FFALIGN(avc_context->width, 16); | 91 t_info.width = FFALIGN(avc_context->width, 16); |
90 t_info.height = FFALIGN(avc_context->height, 16); | 92 t_info.height = FFALIGN(avc_context->height, 16); |
91 t_info.frame_width = avc_context->width; | 93 t_info.frame_width = avc_context->width; |
92 t_info.frame_height = avc_context->height; | 94 t_info.frame_height = avc_context->height; |
93 t_info.offset_x = 0; | 95 t_info.offset_x = 0; |
94 t_info.offset_y = avc_context->height & 0xf; | 96 t_info.offset_y = avc_context->height & 0xf; |
95 /* Swap numerator and denominator as time_base in AVCodecContext gives the | 97 /* Swap numerator and denominator as time_base in AVCodecContext gives the |
96 * time period between frames, but theora_info needs the framerate. */ | 98 * time period between frames, but theora_info needs the framerate. */ |
97 t_info.fps_numerator = avc_context->time_base.den; | 99 t_info.fps_numerator = avc_context->time_base.den; |
98 t_info.fps_denominator = avc_context->time_base.num; | 100 t_info.fps_denominator = avc_context->time_base.num; |
99 if (avc_context->sample_aspect_ratio.num != 0) { | 101 if (avc_context->sample_aspect_ratio.num != 0) { |
100 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num; | 102 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num; |
101 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; | 103 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; |
102 } else { | 104 } else { |
103 t_info.aspect_numerator = 1; | 105 t_info.aspect_numerator = 1; |
104 t_info.aspect_denominator = 1; | 106 t_info.aspect_denominator = 1; |
105 } | 107 } |
106 t_info.colorspace = OC_CS_UNSPECIFIED; | 108 t_info.colorspace = OC_CS_UNSPECIFIED; |
107 t_info.pixelformat = OC_PF_420; | 109 t_info.pixelformat = OC_PF_420; |
108 t_info.keyframe_frequency = avc_context->gop_size; | 110 t_info.keyframe_frequency = avc_context->gop_size; |
109 t_info.keyframe_frequency_force = avc_context->gop_size; | 111 t_info.keyframe_frequency_force = avc_context->gop_size; |
110 t_info.keyframe_mindistance = avc_context->keyint_min; | 112 t_info.keyframe_mindistance = avc_context->keyint_min; |
111 | 113 |
112 t_info.quick_p = 1; | 114 t_info.quick_p = 1; |
113 t_info.dropframes_p = 0; | 115 t_info.dropframes_p = 0; |
114 t_info.keyframe_auto_p = 1; | 116 t_info.keyframe_auto_p = 1; |
115 t_info.keyframe_data_target_bitrate = t_info.target_bitrate * 1.5; | 117 t_info.keyframe_data_target_bitrate = t_info.target_bitrate * 1.5; |
116 t_info.keyframe_auto_threshold = 80; | 118 t_info.keyframe_auto_threshold = 80; |
117 t_info.noise_sensitivity = 1; | 119 t_info.noise_sensitivity = 1; |
118 t_info.sharpness = 0; | 120 t_info.sharpness = 0; |
119 | 121 |
120 if (avc_context->flags & CODEC_FLAG_QSCALE) { | 122 if (avc_context->flags & CODEC_FLAG_QSCALE) { |
121 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 | 123 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 |
122 Theora accepts a quality parameter p, which is: | 124 Theora accepts a quality parameter p, which is: |
123 * 0 <= p <=63 | 125 * 0 <= p <=63 |
124 * an int value | 126 * an int value |
125 */ | 127 */ |
126 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3; | 128 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3; |
127 t_info.target_bitrate = 0; | 129 t_info.target_bitrate = 0; |
128 } else { | 130 } else { |
129 t_info.target_bitrate = avc_context->bit_rate; | 131 t_info.target_bitrate = avc_context->bit_rate; |
130 t_info.quality = 0; | 132 t_info.quality = 0; |
131 } | 133 } |
132 | 134 |
133 /* Now initialise libtheora */ | 135 /* Now initialise libtheora */ |
134 if (theora_encode_init( &(h->t_state), &t_info ) != 0) { | 136 if (theora_encode_init(&(h->t_state), &t_info) != 0) { |
135 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); | 137 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); |
136 return -1; | 138 return -1; |
137 } | 139 } |
138 | 140 |
139 /* Clear up theora_info struct */ | 141 /* Clear up theora_info struct */ |
140 theora_info_clear( &t_info ); | 142 theora_info_clear(&t_info); |
141 | 143 |
142 /* | 144 /* |
143 Output first header packet consisting of theora | 145 Output first header packet consisting of theora |
144 header, comment, and tables. | 146 header, comment, and tables. |
145 | 147 |
147 are concatenated together into ffmpeg's extradata. | 149 are concatenated together into ffmpeg's extradata. |
148 */ | 150 */ |
149 offset = 0; | 151 offset = 0; |
150 | 152 |
151 /* Header */ | 153 /* Header */ |
152 theora_encode_header( &(h->t_state), &o_packet ); | 154 theora_encode_header(&(h->t_state), &o_packet); |
153 if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) | 155 if (concatenate_packet(&offset, avc_context, &o_packet) != 0) |
154 return -1; | 156 return -1; |
155 | 157 |
156 /* Comment */ | 158 /* Comment */ |
157 theora_comment_init( &t_comment ); | 159 theora_comment_init(&t_comment); |
158 theora_encode_comment( &t_comment, &o_packet ); | 160 theora_encode_comment(&t_comment, &o_packet); |
159 if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) | 161 if (concatenate_packet(&offset, avc_context, &o_packet) != 0) |
160 return -1; | 162 return -1; |
161 /* Clear up theora_comment struct before we reset the packet */ | 163 /* Clear up theora_comment struct before we reset the packet */ |
162 theora_comment_clear( &t_comment ); | 164 theora_comment_clear(&t_comment); |
163 /* And despite documentation to the contrary, theora_comment_clear | 165 /* And despite documentation to the contrary, theora_comment_clear |
164 * does not release the packet */ | 166 * does not release the packet */ |
165 ogg_packet_clear(&o_packet); | 167 ogg_packet_clear(&o_packet); |
166 | 168 |
167 /* Tables */ | 169 /* Tables */ |
168 theora_encode_tables( &(h->t_state), &o_packet ); | 170 theora_encode_tables(&(h->t_state), &o_packet); |
169 if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) | 171 if (concatenate_packet(&offset, avc_context, &o_packet) != 0) |
170 return -1; | 172 return -1; |
171 | 173 |
172 /* Set up the output AVFrame */ | 174 /* Set up the output AVFrame */ |
173 avc_context->coded_frame= avcodec_alloc_frame(); | 175 avc_context->coded_frame= avcodec_alloc_frame(); |
174 | 176 |
175 return 0; | 177 return 0; |
176 } | 178 } |
177 | 179 |
178 static int encode_frame( | 180 static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf, |
179 AVCodecContext* avc_context, | 181 int buf_size, void *data) |
180 uint8_t *outbuf, | |
181 int buf_size, | |
182 void *data) | |
183 { | 182 { |
184 yuv_buffer t_yuv_buffer; | 183 yuv_buffer t_yuv_buffer; |
185 TheoraContext *h = avc_context->priv_data; | 184 TheoraContext *h = avc_context->priv_data; |
186 AVFrame *frame = data; | 185 AVFrame *frame = data; |
187 ogg_packet o_packet; | 186 ogg_packet o_packet; |
193 if (frame->linesize[1] != frame->linesize[2]) { | 192 if (frame->linesize[1] != frame->linesize[2]) { |
194 av_log(avc_context, AV_LOG_ERROR, "U and V stride differ\n"); | 193 av_log(avc_context, AV_LOG_ERROR, "U and V stride differ\n"); |
195 return -1; | 194 return -1; |
196 } | 195 } |
197 | 196 |
198 t_yuv_buffer.y_width = FFALIGN(avc_context->width, 16); | 197 t_yuv_buffer.y_width = FFALIGN(avc_context->width, 16); |
199 t_yuv_buffer.y_height = FFALIGN(avc_context->height, 16); | 198 t_yuv_buffer.y_height = FFALIGN(avc_context->height, 16); |
200 t_yuv_buffer.y_stride = frame->linesize[0]; | 199 t_yuv_buffer.y_stride = frame->linesize[0]; |
201 t_yuv_buffer.uv_width = t_yuv_buffer.y_width / 2; | 200 t_yuv_buffer.uv_width = t_yuv_buffer.y_width / 2; |
202 t_yuv_buffer.uv_height = t_yuv_buffer.y_height / 2; | 201 t_yuv_buffer.uv_height = t_yuv_buffer.y_height / 2; |
203 t_yuv_buffer.uv_stride = frame->linesize[1]; | 202 t_yuv_buffer.uv_stride = frame->linesize[1]; |
204 | 203 |
205 t_yuv_buffer.y = frame->data[0]; | 204 t_yuv_buffer.y = frame->data[0]; |
206 t_yuv_buffer.u = frame->data[1]; | 205 t_yuv_buffer.u = frame->data[1]; |
207 t_yuv_buffer.v = frame->data[2]; | 206 t_yuv_buffer.v = frame->data[2]; |
208 | 207 |
209 /* Now call into theora_encode_YUVin */ | 208 /* Now call into theora_encode_YUVin */ |
210 result = theora_encode_YUVin( &(h->t_state), &t_yuv_buffer ); | 209 result = theora_encode_YUVin(&(h->t_state), &t_yuv_buffer); |
211 if (result != 0) { | 210 if (result != 0) { |
212 const char* message; | 211 const char* message; |
213 switch (result) { | 212 switch (result) { |
214 case -1: | 213 case -1: |
215 message = "differing frame sizes"; | 214 message = "differing frame sizes"; |
216 break; | 215 break; |
217 case OC_EINVAL: | 216 case OC_EINVAL: |
218 message = "encoder is not ready or is finished"; | 217 message = "encoder is not ready or is finished"; |
219 break; | 218 break; |
220 default: | 219 default: |
221 message = "unknown reason"; | 220 message = "unknown reason"; |
222 break; | 221 break; |
223 } | 222 } |
224 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result); | 223 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result); |
225 return -1; | 224 return -1; |
226 } | 225 } |
227 | 226 |
228 /* Pick up returned ogg_packet */ | 227 /* Pick up returned ogg_packet */ |
229 result = theora_encode_packetout( &(h->t_state), 0, &o_packet ); | 228 result = theora_encode_packetout(&(h->t_state), 0, &o_packet); |
230 switch (result) { | 229 switch (result) { |
231 case 0: | 230 case 0: |
232 /* No packet is ready */ | 231 /* No packet is ready */ |
233 return 0; | 232 return 0; |
234 case 1: | 233 case 1: |
235 /* Success, we have a packet */ | 234 /* Success, we have a packet */ |
236 break; | 235 break; |
237 default: | 236 default: |
238 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result); | 237 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result); |
239 return -1; | 238 return -1; |
240 } | 239 } |
241 | 240 |
242 /* Copy ogg_packet content out to buffer */ | 241 /* Copy ogg_packet content out to buffer */ |
243 if (buf_size < o_packet.bytes) { | 242 if (buf_size < o_packet.bytes) { |
244 av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n"); | 243 av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n"); |
245 return -1; | 244 return -1; |
246 } | 245 } |
247 memcpy(outbuf, o_packet.packet, o_packet.bytes); | 246 memcpy(outbuf, o_packet.packet, o_packet.bytes); |
248 | 247 |
249 // HACK: does not take codec delay into account (neither does the decoder though) | 248 // HACK: does not take codec delay into account (neither does the decoder though) |
250 avc_context->coded_frame->pts= frame->pts; | 249 avc_context->coded_frame->pts = frame->pts; |
251 | 250 |
252 return o_packet.bytes; | 251 return o_packet.bytes; |
253 } | 252 } |
254 | 253 |
255 static av_cold int encode_close(AVCodecContext* avc_context) | 254 static av_cold int encode_close(AVCodecContext* avc_context) |
257 ogg_packet o_packet; | 256 ogg_packet o_packet; |
258 TheoraContext *h = avc_context->priv_data; | 257 TheoraContext *h = avc_context->priv_data; |
259 int result; | 258 int result; |
260 const char* message; | 259 const char* message; |
261 | 260 |
262 result = theora_encode_packetout( &(h->t_state), 1, &o_packet ); | 261 result = theora_encode_packetout(&(h->t_state), 1, &o_packet); |
263 theora_clear( &(h->t_state) ); | 262 theora_clear(&(h->t_state)); |
264 av_freep(&avc_context->coded_frame); | 263 av_freep(&avc_context->coded_frame); |
265 av_freep(&avc_context->extradata); | 264 av_freep(&avc_context->extradata); |
266 avc_context->extradata_size = 0; | 265 avc_context->extradata_size = 0; |
267 | 266 |
268 switch (result) { | 267 switch (result) { |
269 case 0:/* No packet is ready */ | 268 case 0: /* No packet is ready */ |
270 case -1:/* Encoding finished */ | 269 case -1: /* Encoding finished */ |
271 return 0; | 270 return 0; |
272 case 1: | 271 case 1: |
273 /* We have a packet */ | 272 /* We have a packet */ |
274 message = "gave us a packet"; | 273 message = "gave us a packet"; |
275 break; | 274 break; |
276 default: | 275 default: |
277 message = "unknown reason"; | 276 message = "unknown reason"; |
278 break; | 277 break; |
279 } | 278 } |
280 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed (%s) [%d]\n", message, result); | 279 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed (%s) [%d]\n", message, result); |
281 return -1; | 280 return -1; |
282 } | 281 } |
283 | 282 |
284 static const enum PixelFormat supported_pixel_formats[] = { PIX_FMT_YUV420P, PIX_FMT_NONE }; | 283 static const enum PixelFormat supported_pixel_formats[] = { PIX_FMT_YUV420P, PIX_FMT_NONE }; |
285 | 284 |
286 /*! AVCodec struct exposed to libavcodec */ | 285 /*! AVCodec struct exposed to libavcodec */ |
287 AVCodec libtheora_encoder = | 286 AVCodec libtheora_encoder = { |
288 { | |
289 .name = "libtheora", | 287 .name = "libtheora", |
290 .type = CODEC_TYPE_VIDEO, | 288 .type = CODEC_TYPE_VIDEO, |
291 .id = CODEC_ID_THEORA, | 289 .id = CODEC_ID_THEORA, |
292 .priv_data_size = sizeof(TheoraContext), | 290 .priv_data_size = sizeof(TheoraContext), |
293 .init = encode_init, | 291 .init = encode_init, |