00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00033
00034 #include "libavutil/intreadwrite.h"
00035 #include "libavutil/log.h"
00036 #include "libavutil/base64.h"
00037 #include "avcodec.h"
00038
00039
00040 #include <theora/theoraenc.h>
00041
00042 typedef struct TheoraContext {
00043 th_enc_ctx *t_state;
00044 uint8_t *stats;
00045 int stats_size;
00046 int stats_offset;
00047 int uv_hshift;
00048 int uv_vshift;
00049 int keyframe_mask;
00050 } TheoraContext;
00051
00053 static int concatenate_packet(unsigned int* offset,
00054 AVCodecContext* avc_context,
00055 const ogg_packet* packet)
00056 {
00057 const char* message = NULL;
00058 uint8_t* newdata = NULL;
00059 int newsize = avc_context->extradata_size + 2 + packet->bytes;
00060
00061 if (packet->bytes < 0) {
00062 message = "ogg_packet has negative size";
00063 } else if (packet->bytes > 0xffff) {
00064 message = "ogg_packet is larger than 65535 bytes";
00065 } else if (newsize < avc_context->extradata_size) {
00066 message = "extradata_size would overflow";
00067 } else {
00068 newdata = av_realloc(avc_context->extradata, newsize);
00069 if (!newdata)
00070 message = "av_realloc failed";
00071 }
00072 if (message) {
00073 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
00074 return -1;
00075 }
00076
00077 avc_context->extradata = newdata;
00078 avc_context->extradata_size = newsize;
00079 AV_WB16(avc_context->extradata + (*offset), packet->bytes);
00080 *offset += 2;
00081 memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes);
00082 (*offset) += packet->bytes;
00083 return 0;
00084 }
00085
00086 static int get_stats(AVCodecContext *avctx, int eos)
00087 {
00088 #ifdef TH_ENCCTL_2PASS_OUT
00089 TheoraContext *h = avctx->priv_data;
00090 uint8_t *buf;
00091 int bytes;
00092
00093 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf));
00094 if (bytes < 0) {
00095 av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n");
00096 return -1;
00097 }
00098 if (!eos) {
00099 h->stats = av_fast_realloc(h->stats, &h->stats_size,
00100 h->stats_offset + bytes);
00101 memcpy(h->stats + h->stats_offset, buf, bytes);
00102 h->stats_offset += bytes;
00103 } else {
00104 int b64_size = AV_BASE64_SIZE(h->stats_offset);
00105
00106 memcpy(h->stats, buf, bytes);
00107 avctx->stats_out = av_malloc(b64_size);
00108 av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset);
00109 }
00110 return 0;
00111 #else
00112 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
00113 return -1;
00114 #endif
00115 }
00116
00117
00118
00119 static int submit_stats(AVCodecContext *avctx)
00120 {
00121 #ifdef TH_ENCCTL_2PASS_IN
00122 TheoraContext *h = avctx->priv_data;
00123 int bytes;
00124 if (!h->stats) {
00125 if (!avctx->stats_in) {
00126 av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n");
00127 return -1;
00128 }
00129 h->stats_size = strlen(avctx->stats_in) * 3/4;
00130 h->stats = av_malloc(h->stats_size);
00131 h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size);
00132 }
00133 while (h->stats_size - h->stats_offset > 0) {
00134 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN,
00135 h->stats + h->stats_offset,
00136 h->stats_size - h->stats_offset);
00137 if (bytes < 0) {
00138 av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n");
00139 return -1;
00140 }
00141 if (!bytes)
00142 return 0;
00143 h->stats_offset += bytes;
00144 }
00145 return 0;
00146 #else
00147 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
00148 return -1;
00149 #endif
00150 }
00151
00152 static av_cold int encode_init(AVCodecContext* avc_context)
00153 {
00154 th_info t_info;
00155 th_comment t_comment;
00156 ogg_packet o_packet;
00157 unsigned int offset;
00158 TheoraContext *h = avc_context->priv_data;
00159 uint32_t gop_size = avc_context->gop_size;
00160
00161
00162 th_info_init(&t_info);
00163 t_info.frame_width = FFALIGN(avc_context->width, 16);
00164 t_info.frame_height = FFALIGN(avc_context->height, 16);
00165 t_info.pic_width = avc_context->width;
00166 t_info.pic_height = avc_context->height;
00167 t_info.pic_x = 0;
00168 t_info.pic_y = 0;
00169
00170
00171 t_info.fps_numerator = avc_context->time_base.den;
00172 t_info.fps_denominator = avc_context->time_base.num;
00173 if (avc_context->sample_aspect_ratio.num) {
00174 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num;
00175 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den;
00176 } else {
00177 t_info.aspect_numerator = 1;
00178 t_info.aspect_denominator = 1;
00179 }
00180
00181 if (avc_context->color_primaries == AVCOL_PRI_BT470M)
00182 t_info.colorspace = TH_CS_ITU_REC_470M;
00183 else if (avc_context->color_primaries == AVCOL_PRI_BT470BG)
00184 t_info.colorspace = TH_CS_ITU_REC_470BG;
00185 else
00186 t_info.colorspace = TH_CS_UNSPECIFIED;
00187
00188 if (avc_context->pix_fmt == PIX_FMT_YUV420P)
00189 t_info.pixel_fmt = TH_PF_420;
00190 else if (avc_context->pix_fmt == PIX_FMT_YUV422P)
00191 t_info.pixel_fmt = TH_PF_422;
00192 else if (avc_context->pix_fmt == PIX_FMT_YUV444P)
00193 t_info.pixel_fmt = TH_PF_444;
00194 else {
00195 av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n");
00196 return -1;
00197 }
00198 avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift);
00199
00200 if (avc_context->flags & CODEC_FLAG_QSCALE) {
00201
00202
00203
00204
00205
00206 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
00207 t_info.target_bitrate = 0;
00208 } else {
00209 t_info.target_bitrate = avc_context->bit_rate;
00210 t_info.quality = 0;
00211 }
00212
00213
00214 h->t_state = th_encode_alloc(&t_info);
00215 if (!h->t_state) {
00216 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n");
00217 return -1;
00218 }
00219
00220 h->keyframe_mask = (1 << t_info.keyframe_granule_shift) - 1;
00221
00222 th_info_clear(&t_info);
00223
00224 if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
00225 &gop_size, sizeof(gop_size))) {
00226 av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n");
00227 return -1;
00228 }
00229
00230
00231 if (avc_context->flags & CODEC_FLAG_PASS1) {
00232 if (get_stats(avc_context, 0))
00233 return -1;
00234 } else if (avc_context->flags & CODEC_FLAG_PASS2) {
00235 if (submit_stats(avc_context))
00236 return -1;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246 offset = 0;
00247
00248
00249 th_comment_init(&t_comment);
00250
00251 while (th_encode_flushheader(h->t_state, &t_comment, &o_packet))
00252 if (concatenate_packet(&offset, avc_context, &o_packet))
00253 return -1;
00254
00255 th_comment_clear(&t_comment);
00256
00257
00258 avc_context->coded_frame= avcodec_alloc_frame();
00259
00260 return 0;
00261 }
00262
00263 static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf,
00264 int buf_size, void *data)
00265 {
00266 th_ycbcr_buffer t_yuv_buffer;
00267 TheoraContext *h = avc_context->priv_data;
00268 AVFrame *frame = data;
00269 ogg_packet o_packet;
00270 int result, i;
00271
00272
00273 if (!frame) {
00274 th_encode_packetout(h->t_state, 1, &o_packet);
00275 if (avc_context->flags & CODEC_FLAG_PASS1)
00276 if (get_stats(avc_context, 1))
00277 return -1;
00278 return 0;
00279 }
00280
00281
00282 for (i = 0; i < 3; i++) {
00283 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> (i && h->uv_hshift);
00284 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);
00285 t_yuv_buffer[i].stride = frame->linesize[i];
00286 t_yuv_buffer[i].data = frame->data[i];
00287 }
00288
00289 if (avc_context->flags & CODEC_FLAG_PASS2)
00290 if (submit_stats(avc_context))
00291 return -1;
00292
00293
00294 result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);
00295 if (result) {
00296 const char* message;
00297 switch (result) {
00298 case -1:
00299 message = "differing frame sizes";
00300 break;
00301 case TH_EINVAL:
00302 message = "encoder is not ready or is finished";
00303 break;
00304 default:
00305 message = "unknown reason";
00306 break;
00307 }
00308 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);
00309 return -1;
00310 }
00311
00312 if (avc_context->flags & CODEC_FLAG_PASS1)
00313 if (get_stats(avc_context, 0))
00314 return -1;
00315
00316
00317 result = th_encode_packetout(h->t_state, 0, &o_packet);
00318 switch (result) {
00319 case 0:
00320
00321 return 0;
00322 case 1:
00323
00324 break;
00325 default:
00326 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);
00327 return -1;
00328 }
00329
00330
00331 if (buf_size < o_packet.bytes) {
00332 av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n");
00333 return -1;
00334 }
00335 memcpy(outbuf, o_packet.packet, o_packet.bytes);
00336
00337
00338
00339 avc_context->coded_frame->pts = frame->pts;
00340 avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);
00341
00342 return o_packet.bytes;
00343 }
00344
00345 static av_cold int encode_close(AVCodecContext* avc_context)
00346 {
00347 TheoraContext *h = avc_context->priv_data;
00348
00349 th_encode_free(h->t_state);
00350 av_freep(&h->stats);
00351 av_freep(&avc_context->coded_frame);
00352 av_freep(&avc_context->stats_out);
00353 av_freep(&avc_context->extradata);
00354 avc_context->extradata_size = 0;
00355
00356 return 0;
00357 }
00358
00360 AVCodec ff_libtheora_encoder = {
00361 .name = "libtheora",
00362 .type = AVMEDIA_TYPE_VIDEO,
00363 .id = CODEC_ID_THEORA,
00364 .priv_data_size = sizeof(TheoraContext),
00365 .init = encode_init,
00366 .close = encode_close,
00367 .encode = encode_frame,
00368 .capabilities = CODEC_CAP_DELAY,
00369 .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
00370 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"),
00371 };