Mercurial > libavcodec.hg
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 }; |