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 #include "internal.h"
00039
00040
00041 #include <theora/theoraenc.h>
00042
00043 typedef struct TheoraContext {
00044 th_enc_ctx *t_state;
00045 uint8_t *stats;
00046 int stats_size;
00047 int stats_offset;
00048 int uv_hshift;
00049 int uv_vshift;
00050 int keyframe_mask;
00051 } TheoraContext;
00052
00054 static int concatenate_packet(unsigned int* offset,
00055 AVCodecContext* avc_context,
00056 const ogg_packet* packet)
00057 {
00058 const char* message = NULL;
00059 uint8_t* newdata = NULL;
00060 int newsize = avc_context->extradata_size + 2 + packet->bytes;
00061
00062 if (packet->bytes < 0) {
00063 message = "ogg_packet has negative size";
00064 } else if (packet->bytes > 0xffff) {
00065 message = "ogg_packet is larger than 65535 bytes";
00066 } else if (newsize < avc_context->extradata_size) {
00067 message = "extradata_size would overflow";
00068 } else {
00069 newdata = av_realloc(avc_context->extradata, newsize);
00070 if (!newdata)
00071 message = "av_realloc failed";
00072 }
00073 if (message) {
00074 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
00075 return -1;
00076 }
00077
00078 avc_context->extradata = newdata;
00079 avc_context->extradata_size = newsize;
00080 AV_WB16(avc_context->extradata + (*offset), packet->bytes);
00081 *offset += 2;
00082 memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes);
00083 (*offset) += packet->bytes;
00084 return 0;
00085 }
00086
00087 static int get_stats(AVCodecContext *avctx, int eos)
00088 {
00089 #ifdef TH_ENCCTL_2PASS_OUT
00090 TheoraContext *h = avctx->priv_data;
00091 uint8_t *buf;
00092 int bytes;
00093
00094 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf));
00095 if (bytes < 0) {
00096 av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n");
00097 return -1;
00098 }
00099 if (!eos) {
00100 h->stats = av_fast_realloc(h->stats, &h->stats_size,
00101 h->stats_offset + bytes);
00102 memcpy(h->stats + h->stats_offset, buf, bytes);
00103 h->stats_offset += bytes;
00104 } else {
00105 int b64_size = AV_BASE64_SIZE(h->stats_offset);
00106
00107 memcpy(h->stats, buf, bytes);
00108 avctx->stats_out = av_malloc(b64_size);
00109 av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset);
00110 }
00111 return 0;
00112 #else
00113 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
00114 return -1;
00115 #endif
00116 }
00117
00118
00119
00120 static int submit_stats(AVCodecContext *avctx)
00121 {
00122 #ifdef TH_ENCCTL_2PASS_IN
00123 TheoraContext *h = avctx->priv_data;
00124 int bytes;
00125 if (!h->stats) {
00126 if (!avctx->stats_in) {
00127 av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n");
00128 return -1;
00129 }
00130 h->stats_size = strlen(avctx->stats_in) * 3/4;
00131 h->stats = av_malloc(h->stats_size);
00132 h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size);
00133 }
00134 while (h->stats_size - h->stats_offset > 0) {
00135 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN,
00136 h->stats + h->stats_offset,
00137 h->stats_size - h->stats_offset);
00138 if (bytes < 0) {
00139 av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n");
00140 return -1;
00141 }
00142 if (!bytes)
00143 return 0;
00144 h->stats_offset += bytes;
00145 }
00146 return 0;
00147 #else
00148 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
00149 return -1;
00150 #endif
00151 }
00152
00153 static av_cold int encode_init(AVCodecContext* avc_context)
00154 {
00155 th_info t_info;
00156 th_comment t_comment;
00157 ogg_packet o_packet;
00158 unsigned int offset;
00159 TheoraContext *h = avc_context->priv_data;
00160 uint32_t gop_size = avc_context->gop_size;
00161
00162
00163 th_info_init(&t_info);
00164 t_info.frame_width = FFALIGN(avc_context->width, 16);
00165 t_info.frame_height = FFALIGN(avc_context->height, 16);
00166 t_info.pic_width = avc_context->width;
00167 t_info.pic_height = avc_context->height;
00168 t_info.pic_x = 0;
00169 t_info.pic_y = 0;
00170
00171
00172 t_info.fps_numerator = avc_context->time_base.den;
00173 t_info.fps_denominator = avc_context->time_base.num;
00174 if (avc_context->sample_aspect_ratio.num) {
00175 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num;
00176 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den;
00177 } else {
00178 t_info.aspect_numerator = 1;
00179 t_info.aspect_denominator = 1;
00180 }
00181
00182 if (avc_context->color_primaries == AVCOL_PRI_BT470M)
00183 t_info.colorspace = TH_CS_ITU_REC_470M;
00184 else if (avc_context->color_primaries == AVCOL_PRI_BT470BG)
00185 t_info.colorspace = TH_CS_ITU_REC_470BG;
00186 else
00187 t_info.colorspace = TH_CS_UNSPECIFIED;
00188
00189 if (avc_context->pix_fmt == PIX_FMT_YUV420P)
00190 t_info.pixel_fmt = TH_PF_420;
00191 else if (avc_context->pix_fmt == PIX_FMT_YUV422P)
00192 t_info.pixel_fmt = TH_PF_422;
00193 else if (avc_context->pix_fmt == PIX_FMT_YUV444P)
00194 t_info.pixel_fmt = TH_PF_444;
00195 else {
00196 av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n");
00197 return -1;
00198 }
00199 avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift);
00200
00201 if (avc_context->flags & CODEC_FLAG_QSCALE) {
00202
00203
00204
00205
00206
00207 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
00208 t_info.target_bitrate = 0;
00209 } else {
00210 t_info.target_bitrate = avc_context->bit_rate;
00211 t_info.quality = 0;
00212 }
00213
00214
00215 h->t_state = th_encode_alloc(&t_info);
00216 if (!h->t_state) {
00217 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n");
00218 return -1;
00219 }
00220
00221 h->keyframe_mask = (1 << t_info.keyframe_granule_shift) - 1;
00222
00223 th_info_clear(&t_info);
00224
00225 if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
00226 &gop_size, sizeof(gop_size))) {
00227 av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n");
00228 return -1;
00229 }
00230
00231
00232 if (avc_context->flags & CODEC_FLAG_PASS1) {
00233 if (get_stats(avc_context, 0))
00234 return -1;
00235 } else if (avc_context->flags & CODEC_FLAG_PASS2) {
00236 if (submit_stats(avc_context))
00237 return -1;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 offset = 0;
00248
00249
00250 th_comment_init(&t_comment);
00251
00252 while (th_encode_flushheader(h->t_state, &t_comment, &o_packet))
00253 if (concatenate_packet(&offset, avc_context, &o_packet))
00254 return -1;
00255
00256 th_comment_clear(&t_comment);
00257
00258
00259 avc_context->coded_frame= avcodec_alloc_frame();
00260
00261 return 0;
00262 }
00263
00264 static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt,
00265 const AVFrame *frame, int *got_packet)
00266 {
00267 th_ycbcr_buffer t_yuv_buffer;
00268 TheoraContext *h = avc_context->priv_data;
00269 ogg_packet o_packet;
00270 int result, i, ret;
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 ((ret = ff_alloc_packet2(avc_context, pkt, o_packet.bytes)) < 0)
00332 return ret;
00333 memcpy(pkt->data, o_packet.packet, o_packet.bytes);
00334
00335
00336
00337 pkt->pts = pkt->dts = frame->pts;
00338 avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);
00339 if (avc_context->coded_frame->key_frame)
00340 pkt->flags |= AV_PKT_FLAG_KEY;
00341 *got_packet = 1;
00342
00343 return 0;
00344 }
00345
00346 static av_cold int encode_close(AVCodecContext* avc_context)
00347 {
00348 TheoraContext *h = avc_context->priv_data;
00349
00350 th_encode_free(h->t_state);
00351 av_freep(&h->stats);
00352 av_freep(&avc_context->coded_frame);
00353 av_freep(&avc_context->stats_out);
00354 av_freep(&avc_context->extradata);
00355 avc_context->extradata_size = 0;
00356
00357 return 0;
00358 }
00359
00361 AVCodec ff_libtheora_encoder = {
00362 .name = "libtheora",
00363 .type = AVMEDIA_TYPE_VIDEO,
00364 .id = CODEC_ID_THEORA,
00365 .priv_data_size = sizeof(TheoraContext),
00366 .init = encode_init,
00367 .close = encode_close,
00368 .encode2 = encode_frame,
00369 .capabilities = CODEC_CAP_DELAY,
00370 .pix_fmts = (const enum PixelFormat[]){
00371 PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE
00372 },
00373 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"),
00374 };