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,