1/* 2 * Copyright (c) 2006 Paul Richards <paul.richards@gmail.com> 3 * 4 * This file is part of Libav. 5 * 6 * Libav is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * Libav is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with Libav; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21/** 22 * @file 23 * @brief Theora encoder using libtheora. 24 * @author Paul Richards <paul.richards@gmail.com> 25 * 26 * A lot of this is copy / paste from other output codecs in 27 * libavcodec or pure guesswork (or both). 28 * 29 * I have used t_ prefixes on variables which are libtheora types 30 * and o_ prefixes on variables which are libogg types. 31 */ 32 33/* Libav includes */ 34#include "libavutil/intreadwrite.h" 35#include "libavutil/log.h" 36#include "libavutil/base64.h" 37#include "avcodec.h" 38 39/* libtheora includes */ 40#include <theora/theoraenc.h> 41 42typedef struct TheoraContext { 43 th_enc_ctx *t_state; 44 uint8_t *stats; 45 int stats_size; 46 int stats_offset; 47 int uv_hshift; 48 int uv_vshift; 49 int keyframe_mask; 50} TheoraContext; 51 52/** Concatenate an ogg_packet into the extradata. */ 53static int concatenate_packet(unsigned int* offset, 54 AVCodecContext* avc_context, 55 const ogg_packet* packet) 56{ 57 const char* message = NULL; 58 uint8_t* newdata = NULL; 59 int newsize = avc_context->extradata_size + 2 + packet->bytes; 60 61 if (packet->bytes < 0) { 62 message = "ogg_packet has negative size"; 63 } else if (packet->bytes > 0xffff) { 64 message = "ogg_packet is larger than 65535 bytes"; 65 } else if (newsize < avc_context->extradata_size) { 66 message = "extradata_size would overflow"; 67 } else { 68 newdata = av_realloc(avc_context->extradata, newsize); 69 if (!newdata) 70 message = "av_realloc failed"; 71 } 72 if (message) { 73 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message); 74 return -1; 75 } 76 77 avc_context->extradata = newdata; 78 avc_context->extradata_size = newsize; 79 AV_WB16(avc_context->extradata + (*offset), packet->bytes); 80 *offset += 2; 81 memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes); 82 (*offset) += packet->bytes; 83 return 0; 84} 85 86static int get_stats(AVCodecContext *avctx, int eos) 87{ 88#ifdef TH_ENCCTL_2PASS_OUT 89 TheoraContext *h = avctx->priv_data; 90 uint8_t *buf; 91 int bytes; 92 93 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf)); 94 if (bytes < 0) { 95 av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n"); 96 return -1; 97 } 98 if (!eos) { 99 h->stats = av_fast_realloc(h->stats, &h->stats_size, 100 h->stats_offset + bytes); 101 memcpy(h->stats + h->stats_offset, buf, bytes); 102 h->stats_offset += bytes; 103 } else { 104 int b64_size = AV_BASE64_SIZE(h->stats_offset); 105 // libtheora generates a summary header at the end 106 memcpy(h->stats, buf, bytes); 107 avctx->stats_out = av_malloc(b64_size); 108 av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset); 109 } 110 return 0; 111#else 112 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n"); 113 return -1; 114#endif 115} 116 117// libtheora won't read the entire buffer we give it at once, so we have to 118// repeatedly submit it... 119static int submit_stats(AVCodecContext *avctx) 120{ 121#ifdef TH_ENCCTL_2PASS_IN 122 TheoraContext *h = avctx->priv_data; 123 int bytes; 124 if (!h->stats) { 125 if (!avctx->stats_in) { 126 av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n"); 127 return -1; 128 } 129 h->stats_size = strlen(avctx->stats_in) * 3/4; 130 h->stats = av_malloc(h->stats_size); 131 h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size); 132 } 133 while (h->stats_size - h->stats_offset > 0) { 134 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN, 135 h->stats + h->stats_offset, 136 h->stats_size - h->stats_offset); 137 if (bytes < 0) { 138 av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n"); 139 return -1; 140 } 141 if (!bytes) 142 return 0; 143 h->stats_offset += bytes; 144 } 145 return 0; 146#else 147 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n"); 148 return -1; 149#endif 150} 151 152static av_cold int encode_init(AVCodecContext* avc_context) 153{ 154 th_info t_info; 155 th_comment t_comment; 156 ogg_packet o_packet; 157 unsigned int offset; 158 TheoraContext *h = avc_context->priv_data; 159 uint32_t gop_size = avc_context->gop_size; 160 161 /* Set up the theora_info struct */ 162 th_info_init(&t_info); 163 t_info.frame_width = FFALIGN(avc_context->width, 16); 164 t_info.frame_height = FFALIGN(avc_context->height, 16); 165 t_info.pic_width = avc_context->width; 166 t_info.pic_height = avc_context->height; 167 t_info.pic_x = 0; 168 t_info.pic_y = 0; 169 /* Swap numerator and denominator as time_base in AVCodecContext gives the 170 * time period between frames, but theora_info needs the framerate. */ 171 t_info.fps_numerator = avc_context->time_base.den; 172 t_info.fps_denominator = avc_context->time_base.num; 173 if (avc_context->sample_aspect_ratio.num) { 174 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num; 175 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den; 176 } else { 177 t_info.aspect_numerator = 1; 178 t_info.aspect_denominator = 1; 179 } 180 181 if (avc_context->color_primaries == AVCOL_PRI_BT470M) 182 t_info.colorspace = TH_CS_ITU_REC_470M; 183 else if (avc_context->color_primaries == AVCOL_PRI_BT470BG) 184 t_info.colorspace = TH_CS_ITU_REC_470BG; 185 else 186 t_info.colorspace = TH_CS_UNSPECIFIED; 187 188 if (avc_context->pix_fmt == PIX_FMT_YUV420P) 189 t_info.pixel_fmt = TH_PF_420; 190 else if (avc_context->pix_fmt == PIX_FMT_YUV422P) 191 t_info.pixel_fmt = TH_PF_422; 192 else if (avc_context->pix_fmt == PIX_FMT_YUV444P) 193 t_info.pixel_fmt = TH_PF_444; 194 else { 195 av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n"); 196 return -1; 197 } 198 avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift); 199 200 if (avc_context->flags & CODEC_FLAG_QSCALE) { 201 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10 202 Theora accepts a quality parameter p, which is: 203 * 0 <= p <=63 204 * an int value 205 */ 206 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3; 207 t_info.target_bitrate = 0; 208 } else { 209 t_info.target_bitrate = avc_context->bit_rate; 210 t_info.quality = 0; 211 } 212 213 /* Now initialise libtheora */ 214 h->t_state = th_encode_alloc(&t_info); 215 if (!h->t_state) { 216 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n"); 217 return -1; 218 } 219 220 h->keyframe_mask = (1 << t_info.keyframe_granule_shift) - 1; 221 /* Clear up theora_info struct */ 222 th_info_clear(&t_info); 223 224 if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE, 225 &gop_size, sizeof(gop_size))) { 226 av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n"); 227 return -1; 228 } 229 230 // need to enable 2 pass (via TH_ENCCTL_2PASS_) before encoding headers 231 if (avc_context->flags & CODEC_FLAG_PASS1) { 232 if (get_stats(avc_context, 0)) 233 return -1; 234 } else if (avc_context->flags & CODEC_FLAG_PASS2) { 235 if (submit_stats(avc_context)) 236 return -1; 237 } 238 239 /* 240 Output first header packet consisting of theora 241 header, comment, and tables. 242 243 Each one is prefixed with a 16bit size, then they 244 are concatenated together into libavcodec's extradata. 245 */ 246 offset = 0; 247 248 /* Headers */ 249 th_comment_init(&t_comment); 250 251 while (th_encode_flushheader(h->t_state, &t_comment, &o_packet)) 252 if (concatenate_packet(&offset, avc_context, &o_packet)) 253 return -1; 254 255 th_comment_clear(&t_comment); 256 257 /* Set up the output AVFrame */ 258 avc_context->coded_frame= avcodec_alloc_frame(); 259 260 return 0; 261} 262 263static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf, 264 int buf_size, void *data) 265{ 266 th_ycbcr_buffer t_yuv_buffer; 267 TheoraContext *h = avc_context->priv_data; 268 AVFrame *frame = data; 269 ogg_packet o_packet; 270 int result, i; 271 272 // EOS, finish and get 1st pass stats if applicable 273 if (!frame) { 274 th_encode_packetout(h->t_state, 1, &o_packet); 275 if (avc_context->flags & CODEC_FLAG_PASS1) 276 if (get_stats(avc_context, 1)) 277 return -1; 278 return 0; 279 } 280 281 /* Copy planes to the theora yuv_buffer */ 282 for (i = 0; i < 3; i++) { 283 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> (i && h->uv_hshift); 284 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift); 285 t_yuv_buffer[i].stride = frame->linesize[i]; 286 t_yuv_buffer[i].data = frame->data[i]; 287 } 288 289 if (avc_context->flags & CODEC_FLAG_PASS2) 290 if (submit_stats(avc_context)) 291 return -1; 292 293 /* Now call into theora_encode_YUVin */ 294 result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer); 295 if (result) { 296 const char* message; 297 switch (result) { 298 case -1: 299 message = "differing frame sizes"; 300 break; 301 case TH_EINVAL: 302 message = "encoder is not ready or is finished"; 303 break; 304 default: 305 message = "unknown reason"; 306 break; 307 } 308 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result); 309 return -1; 310 } 311 312 if (avc_context->flags & CODEC_FLAG_PASS1) 313 if (get_stats(avc_context, 0)) 314 return -1; 315 316 /* Pick up returned ogg_packet */ 317 result = th_encode_packetout(h->t_state, 0, &o_packet); 318 switch (result) { 319 case 0: 320 /* No packet is ready */ 321 return 0; 322 case 1: 323 /* Success, we have a packet */ 324 break; 325 default: 326 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result); 327 return -1; 328 } 329 330 /* Copy ogg_packet content out to buffer */ 331 if (buf_size < o_packet.bytes) { 332 av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n"); 333 return -1; 334 } 335 memcpy(outbuf, o_packet.packet, o_packet.bytes); 336 337 // HACK: assumes no encoder delay, this is true until libtheora becomes 338 // multithreaded (which will be disabled unless explictly requested) 339 avc_context->coded_frame->pts = frame->pts; 340 avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask); 341 342 return o_packet.bytes; 343} 344 345static av_cold int encode_close(AVCodecContext* avc_context) 346{ 347 TheoraContext *h = avc_context->priv_data; 348 349 th_encode_free(h->t_state); 350 av_freep(&h->stats); 351 av_freep(&avc_context->coded_frame); 352 av_freep(&avc_context->stats_out); 353 av_freep(&avc_context->extradata); 354 avc_context->extradata_size = 0; 355 356 return 0; 357} 358 359/** AVCodec struct exposed to libavcodec */ 360AVCodec ff_libtheora_encoder = { 361 .name = "libtheora", 362 .type = AVMEDIA_TYPE_VIDEO, 363 .id = CODEC_ID_THEORA, 364 .priv_data_size = sizeof(TheoraContext), 365 .init = encode_init, 366 .close = encode_close, 367 .encode = encode_frame, 368 .capabilities = CODEC_CAP_DELAY, // needed to get the statsfile summary 369 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, 370 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"), 371}; 372