comparison libtheoraenc.c @ 10555:3d8ab953a869 libavcodec

Support 4:2:2 and 4:4:4 subsampling in libtheora encoding
author conrad
date Sun, 22 Nov 2009 21:08:43 +0000
parents deabe9f7571b
children 54e322044750
comparison
equal deleted inserted replaced
10554:deabe9f7571b 10555:3d8ab953a869
42 typedef struct TheoraContext { 42 typedef struct TheoraContext {
43 th_enc_ctx *t_state; 43 th_enc_ctx *t_state;
44 uint8_t *stats; 44 uint8_t *stats;
45 int stats_size; 45 int stats_size;
46 int stats_offset; 46 int stats_offset;
47 int uv_hshift;
48 int uv_vshift;
47 } TheoraContext; 49 } TheoraContext;
48 50
49 /*! 51 /*!
50 Concatenates an ogg_packet into the extradata. 52 Concatenates an ogg_packet into the extradata.
51 */ 53 */
165 } else { 167 } else {
166 t_info.aspect_numerator = 1; 168 t_info.aspect_numerator = 1;
167 t_info.aspect_denominator = 1; 169 t_info.aspect_denominator = 1;
168 } 170 }
169 t_info.colorspace = TH_CS_UNSPECIFIED; 171 t_info.colorspace = TH_CS_UNSPECIFIED;
170 t_info.pixel_fmt = TH_PF_420; 172
173 if (avc_context->pix_fmt == PIX_FMT_YUV420P)
174 t_info.pixel_fmt = TH_PF_420;
175 else if (avc_context->pix_fmt == PIX_FMT_YUV422P)
176 t_info.pixel_fmt = TH_PF_422;
177 else if (avc_context->pix_fmt == PIX_FMT_YUV444P)
178 t_info.pixel_fmt = TH_PF_444;
179 else {
180 av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n");
181 return -1;
182 }
183 avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift);
171 184
172 if (avc_context->flags & CODEC_FLAG_QSCALE) { 185 if (avc_context->flags & CODEC_FLAG_QSCALE) {
173 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 186 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10
174 Theora accepts a quality parameter p, which is: 187 Theora accepts a quality parameter p, which is:
175 * 0 <= p <=63 188 * 0 <= p <=63
238 TheoraContext *h = avc_context->priv_data; 251 TheoraContext *h = avc_context->priv_data;
239 AVFrame *frame = data; 252 AVFrame *frame = data;
240 ogg_packet o_packet; 253 ogg_packet o_packet;
241 int result, i; 254 int result, i;
242 255
243 assert(avc_context->pix_fmt == PIX_FMT_YUV420P);
244
245 // EOS, finish and get 1st pass stats if applicable 256 // EOS, finish and get 1st pass stats if applicable
246 if (!frame) { 257 if (!frame) {
247 th_encode_packetout(h->t_state, 1, &o_packet); 258 th_encode_packetout(h->t_state, 1, &o_packet);
248 if (avc_context->flags & CODEC_FLAG_PASS1) 259 if (avc_context->flags & CODEC_FLAG_PASS1)
249 if (get_stats(avc_context, 1)) 260 if (get_stats(avc_context, 1))
251 return 0; 262 return 0;
252 } 263 }
253 264
254 /* Copy planes to the theora yuv_buffer */ 265 /* Copy planes to the theora yuv_buffer */
255 for (i = 0; i < 3; i++) { 266 for (i = 0; i < 3; i++) {
256 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> !!i; 267 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> (i && h->uv_hshift);
257 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> !!i; 268 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);
258 t_yuv_buffer[i].stride = frame->linesize[i]; 269 t_yuv_buffer[i].stride = frame->linesize[i];
259 t_yuv_buffer[i].data = frame->data[i]; 270 t_yuv_buffer[i].data = frame->data[i];
260 } 271 }
261 272
262 if (avc_context->flags & CODEC_FLAG_PASS2) 273 if (avc_context->flags & CODEC_FLAG_PASS2)
325 avc_context->extradata_size = 0; 336 avc_context->extradata_size = 0;
326 337
327 return 0; 338 return 0;
328 } 339 }
329 340
330 static const enum PixelFormat supported_pixel_formats[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
331
332 /*! AVCodec struct exposed to libavcodec */ 341 /*! AVCodec struct exposed to libavcodec */
333 AVCodec libtheora_encoder = { 342 AVCodec libtheora_encoder = {
334 .name = "libtheora", 343 .name = "libtheora",
335 .type = CODEC_TYPE_VIDEO, 344 .type = CODEC_TYPE_VIDEO,
336 .id = CODEC_ID_THEORA, 345 .id = CODEC_ID_THEORA,
337 .priv_data_size = sizeof(TheoraContext), 346 .priv_data_size = sizeof(TheoraContext),
338 .init = encode_init, 347 .init = encode_init,
339 .close = encode_close, 348 .close = encode_close,
340 .encode = encode_frame, 349 .encode = encode_frame,
341 .capabilities = CODEC_CAP_DELAY, // needed to get the statsfile summary 350 .capabilities = CODEC_CAP_DELAY, // needed to get the statsfile summary
342 .pix_fmts = supported_pixel_formats, 351 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
343 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"), 352 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"),
344 }; 353 };